WoWInterface SVN LibSpellName2SID

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /populator
    from Rev 188 to Rev 189
    Reverse comparison

Rev 188 → Rev 189

tags/LibSpellName2SID-Populator-1.1.11b/LICENSE.txt New file
0,0 → 1,16
Copyright (C) 2017-2020 aallkkaa <aallkkaa@gmx.com>
 
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
 
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
tags/LibSpellName2SID-Populator-1.1.11b/LibSpellName2SID-1.1-Populator.lua New file
0,0 → 1,2382
--[[
LibSpellName2SID-1.1: Populator
Notes: Populates the LibSpellName2SID databases
http://svn.wowinterface.com/listing.php?repname=LibSpellName2ID&path=%2Fpopulator%2F#_populator_
]]--
----------------------------------------------------------------
-- LEGAL NOTICE (ABBREVIATED) -- --
-----------------------------------
--[[
Copyright (C) 2017-2020 aallkkaa <aallkkaa@gmx.com> [*]
[*] This e-mail adress is provided for legal purposes only. For all other purposes (usage help, bug
reports, suggestions, etc) please use the project's page hosted on the WoWInterface website, at:
https://www.wowinterface.com/downloads/info24509-LibSpellName2SID.html
 
This software is licensed to you under the terms of an MIT license. A file named LICENSE.txt, which
should have been included with your copy of this software, describes the licensing terms.
]]--
----------------------------------------------------------------
 
local AddonName, AddonEnv = ...;
 
-- Local copies of the saved variables' tables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES, DEBUG_messages and METAdata
local SN2SID_table, SN2SID_PASSIVES_table, DEBUGmsgs, METADATA_table;
 
-- 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
 
-- Metadata flags
local updateGeneralTabMetadata, updateClassMetadata = false, false;
 
-- (Usually) One-time fetched values
local generalTabName, universalRaceName, universalClassName;
local petFamily, petSpec;
 
-- Table for storing of dealyed-fetch spells' information (namely de subSpellName )
local delayedSpellsInfo_tbl = {
-- Id<number> = API_call,
};
 
-- "Manually" added/modified spells - normally AFTER regular update functions were called
local postUpdate_Spells2Add = {
["General"] = {
["AzeriteEssences"] = {
-- https://www.wowhead.com/guides/heart-of-azeroth-essence-overview#list-of-all-essences and
-- https://www.wowinterface.com/forums/showpost.php?p=332914&postcount=2
["Heart Essence"] = 296208, -- Generic place-holder
-- Rank 1 (unspecified) --
-- Essences Used by All Roles
["Concentrated Flame"] = 295373,
["Worldvein Resonance"] = 295186,
["Ripple in Space"] = 302731,
["Vision of Perfection"] = 296325,
["Memory of Lucid Dreams"] = 298357,
["Conflict"] = 303823,
-- Tank Essences
["Aegis of the Deep"] = 298168,
["Empowered Null Barrier"] = 295746,
["Suppressing Pulse"] = 293031,
["Azeroth's Undying Gift"] = 293019,
["Anima of Death"] = 294926,
-- Healer Essences
["Overcharge Mana"] = 296072,
["Refreshment"] = 296197,
["Standstill"] = 296094,
["Life-Binder's Invocation"] = 293032,
["Vitality Conduit"] = 296230,
-- DPS Essences
["The Unbound Force"] = 298452,
["Purifying Blast"] = 295337,
["Blood of the Enemy"] = 297108,
["Focused Azerite Beam"] = 295258,
["Guardian of Azeroth"] = 295840,
-- Rank 1 --
-- Essences Used by All Roles
["Concentrated Flame(Rank 1)"] = 295373,
["Worldvein Resonance(Rank 1)"] = 295186,
["Ripple in Space(Rank 1)"] = 302731,
["Vision of Perfection(Rank 1)"] = 296325,
["Memory of Lucid Dreams(Rank 1)"] = 298357,
["Conflict(Rank 1)"] = 303823,
-- Tank Essences
["Aegis of the Deep(Rank 1)"] = 298168,
["Empowered Null Barrier(Rank 1)"] = 295746,
["Suppressing Pulse(Rank 1)"] = 293031,
["Azeroth's Undying Gift(Rank 1)"] = 293019,
["Anima of Death(Rank 1)"] = 294926,
-- Healer Essences
["Overcharge Mana(Rank 1)"] = 296072,
["Refreshment(Rank 1)"] = 296197,
["Standstill(Rank 1)"] = 296094,
["Life-Binder's Invocation(Rank 1)"] = 293032,
["Vitality Conduit(Rank 1)"] = 296230,
-- DPS Essences
["The Unbound Force(Rank 1)"] = 298452,
["Purifying Blast(Rank 1)"] = 295337,
["Blood of the Enemy(Rank 1)"] = 297108,
["Focused Azerite Beam(Rank 1)"] = 295258,
["Guardian of Azeroth(Rank 1)"] = 295840,
-- Rank 2 --
-- Essences Used by All Roles
["Concentrated Flame(Rank 2)"] = 299349,
["Worldvein Resonance(Rank 2)"] = 298628,
["Ripple in Space(Rank 2)"] = 302982,
["Vision of Perfection(Rank 2)"] = 299368,
["Memory of Lucid Dreams(Rank 2)"] = 299372,
["Conflict(Rank 2)"] = 304088,
-- Tank Essences
["Aegis of the Deep(Rank 2)"] = 299273,
["Empowered Null Barrier(Rank 2)"] = 300015,
["Suppressing Pulse(Rank 2)"] = 300009,
["Azeroth's Undying Gift(Rank 2)"] = 298080,
["Anima of Death(Rank 2)"] = 300002,
-- Healer Essences
["Overcharge Mana(Rank 2)"] = 299875,
["Refreshment(Rank 2)"] = 299932,
["Standstill(Rank 2)"] = 299882,
["Life-Binder's Invocation(Rank 2)"] = 299943,
["Vitality Conduit(Rank 2)"] = 299958,
-- DPS Essences
["The Unbound Force(Rank 2)"] = 299376,
["Purifying Blast(Rank 2)"] = 299345,
["Blood of the Enemy(Rank 2)"] = 298273,
["Focused Azerite Beam(Rank 2)"] = 299336,
["Guardian of Azeroth(Rank 2)"] = 299355,
-- Rank 3 --
-- Essences Used by All Roles
["Concentrated Flame(Rank 3)"] = 299353,
["Worldvein Resonance(Rank 3)"] = 299334,
["Ripple in Space(Rank 3)"] = 302983,
["Vision of Perfection(Rank 3)"] = 299370,
["Memory of Lucid Dreams(Rank 3)"] = 299374,
["Conflict(Rank 3)"] = 304121,
-- Tank Essences
["Aegis of the Deep(Rank 3)"] = 299275,
["Empowered Null Barrier(Rank 3)"] = 300016,
["Suppressing Pulse(Rank 3)"] = 300010,
["Azeroth's Undying Gift(Rank 3)"] = 298081,
["Anima of Death(Rank 3)"] = 300003,
-- Healer Essences
["Overcharge Mana(Rank 3)"] = 299876,
["Refreshment(Rank 3)"] = 299933,
["Standstill(Rank 3)"] = 299883,
["Life-Binder's Invocation(Rank 3)"] = 299944,
["Vitality Conduit(Rank 3)"] = 299959,
-- DPS Essences
["The Unbound Force(Rank 3)"] = 299378,
["Purifying Blast(Rank 3)"] = 299347,
["Blood of the Enemy(Rank 3)"] = 298277,
["Focused Azerite Beam(Rank 3)"] = 299338,
["Guardian of Azeroth(Rank 3)"] = 299358,
-- Rank 4 (same IDs as Rank 3) --
-- Essences Used by All Roles
["Concentrated Flame(Rank 4)"] = 299353,
["Worldvein Resonance(Rank 4)"] = 299334,
["Ripple in Space(Rank 4)"] = 302983,
["Vision of Perfection(Rank 4)"] = 299370,
["Memory of Lucid Dreams(Rank 4)"] = 299374,
["Conflict(Rank 4)"] = 304121,
-- Tank Essences
["Aegis of the Deep(Rank 4)"] = 299275,
["Empowered Null Barrier(Rank 4)"] = 300016,
["Suppressing Pulse(Rank 4)"] = 300010,
["Azeroth's Undying Gift(Rank 4)"] = 298081,
["Anima of Death(Rank 4)"] = 300003,
-- Healer Essences
["Overcharge Mana(Rank 4)"] = 299876,
["Refreshment(Rank 4)"] = 299933,
["Standstill(Rank 4)"] = 299883,
["Life-Binder's Invocation(Rank 4)"] = 299944,
["Vitality Conduit(Rank 4)"] = 299959,
-- DPS Essences
["The Unbound Force(Rank 4)"] = 299378,
["Purifying Blast(Rank 4)"] = 299347,
["Blood of the Enemy(Rank 4)"] = 298277,
["Focused Azerite Beam(Rank 4)"] = 299338,
["Guardian of Azeroth(Rank 4)"] = 299358,
},
["Racials"] = {
["Mechagnome"] = {
-- This race's Active abilities don't have the "Racial" sbutext field, thus were being
-- put in the "Others" category.
["Hyper Organic Light Originator"] = 312924,
["Skeleton Pinkie"] = 312890,
},
["VoidElf"] = {
-- ["Spatial Rift"] = 256948,
["Spatial Rift(Step 1)"] = 256948, -- Tear rift!
["Spatial Rift(Step 2)"] = 257040, -- Teleport!
},
},
["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
},
},
["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"] = {
["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
["Ray"] = { -- "Nether Ray" got renamed to "Ray" in WoW 8.2.0
["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,
-- #1
-- 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.
--
-- #2
-- 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).
},
["Flyouts"] = {
-- 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
},
},
},
-- All Rogue Poisons are fetchable from the logged in character. The bellow is no longer needed.
["ROGUE"] = {
["Assassination"] = {
["Poisons"] = 66,
["Envenom"] = 32645, -- Replaces Eviscerate at level 36
["Eviscerate"] = 196819, -- Is replaced by Envenom at level 36
},
["Subtlety"] = {
["Poisons"] = 66,
},
["Outlaw"] = {
["Poisons"] = 66,
},
["FlyoutsTOGET"] = {
["Poisons"] = 66,
},
},
["SHAMAN"] = {
["Elemental"] = {
["Bloodlust"] = 2825, -- Horde
["Heroism"] = 32182, -- Alliance
["Bloodlust(NoShamanism)"] = 2825, -- Horde
["Heroism(NoShamanism)"] = 32182, -- Alliance
["Bloodlust(Shamanism)"] = 204361, -- Horde: Bloodlust with PvP talent: Shamanism
["Heroism(Shamanism)"] = 204362, -- Alliance: Heroism with PvP talent: Shamanism
 
["Hex Variants"] = 106,
},
["Enhancement"] = {
["Bloodlust"] = 2825, -- Horde
["Heroism"] = 32182, -- Alliance
["Bloodlust(NoShamanism)"] = 2825, -- Horde
["Heroism(NoShamanism)"] = 32182, -- Alliance
["Bloodlust(Shamanism)"] = 204361, -- Horde: Bloodlust with PvP talent: Shamanism
["Heroism(Shamanism)"] = 204362, -- Alliance: Heroism with PvP talent: Shamanism
 
["Hex Variants"] = 106,
},
["Restoration"] = {
["Bloodlust"] = 2825, -- Horde
["Heroism"] = 32182, -- Alliance
["Bloodlust(NoShamanism)"] = 2825, -- Horde
["Heroism(NoShamanism)"] = 32182, -- Alliance
["Bloodlust(Shamanism)"] = 204361, -- Horde: Bloodlust with PvP talent: Shamanism
["Heroism(Shamanism)"] = 204362, -- Alliance: Heroism with PvP talent: Shamanism
["Hex Variants"] = 106,
},
["FlyoutsTOGET"] = {
["Hex Variants"] = 106,
-- #1
-- 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.
--
-- #2
-- 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).
},
["Pets"] = {
-- In WoW 8.x.y, only the Elemental specialization has controllable pets, and only 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 all three Shaman specs, 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
},
},
},
["WARRIOR"] = {
["Protection"] = {
["Charge"] = 100, -- Replaced by Intercept at level 28
["Intercept"] = 198304, -- Replaces Charge at level 28
},
},
};
 
local postUpdate_Spells2Add_PASSIVES = {
["General"] = {
["AzeriteEssences"] = {
-- https://www.wowhead.com/guides/heart-of-azeroth-essence-overview#list-of-all-essences and
-- https://www.wowinterface.com/forums/showpost.php?p=332914&postcount=2
-- Rank 1 (unspecified) --
-- Essences Used by All Roles
["Ancient Flame"] = 295365,
["Lifeblood"] = 295078,
["Reality Shift"] = 302916,
["Strive for Perfection"] = 296320,
["Lucid Dreams"] = 298268,
["Strife"] = 304081,
-- Tank Essences
["Stand Your Ground"] = 298193,
["Null Barrier"] = 295750,
["Sphere of Suppression"] = 294910,
["Hardened Azerite"] = 294668,
["Anima of Life"] = 294964,
-- Healer Essences
["The Ever-Rising Tide"] = 296050,
["The Well of Existence"] = 296136,
["Artifice of Time"] = 296081,
["Seed of Eonar"] = 296207,
["Transference"] = 303448,
-- DPS Essences
["Reckless Force"] = 298407,
["Purification Protocol"] = 295293,
["Blood-Soaked"] = 297147,
["Focused Energy"] = 295246,
["Condensed Life-Force"] = 295834,
-- Rank 1 --
-- Essences Used by All Roles
["Ancient Flame(Rank 1)"] = 295365,
["Lifeblood(Rank 1)"] = 295078,
["Reality Shift(Rank 1)"] = 302916,
["Strive for Perfection(Rank 1)"] = 296320,
["Lucid Dreams(Rank 1)"] = 298268,
["Strife(Rank 1)"] = 304081,
-- Tank Essences
["Stand Your Ground(Rank 1)"] = 298193,
["Null Barrier(Rank 1)"] = 295750,
["Sphere of Suppression(Rank 1)"] = 294910,
["Hardened Azerite(Rank 1)"] = 294668,
["Anima of Life(Rank 1)"] = 294964,
-- Healer Essences
["The Ever-Rising Tide(Rank 1)"] = 296050,
["The Well of Existence(Rank 1)"] = 296136,
["Artifice of Time(Rank 1)"] = 296081,
["Seed of Eonar(Rank 1)"] = 296207,
["Transference(Rank 1)"] = 303448,
-- DPS Essences
["Reckless Force(Rank 1)"] = 298407,
["Purification Protocol(Rank 1)"] = 295293,
["Blood-Soaked(Rank 1)"] = 297147,
["Focused Energy(Rank 1)"] = 295246,
["Condensed Life-Force(Rank 1)"] = 295834,
-- Rank 2
-- Essences Used by All Roles
["Ancient Flame(Rank 2)"] = 299348,
["Lifeblood(Rank 2)"] = 298627,
["Reality Shift(Rank 2)"] = 302984,
["Strive for Perfection(Rank 2)"] = 299367,
["Lucid Dreams(Rank 2)"] = 299371,
["Strife(Rank 2)"] = 304089,
-- Tank Essences
["Stand Your Ground(Rank 2)"] = 299274,
["Null Barrier(Rank 2)"] = 300018,
["Sphere of Suppression(Rank 2)"] = 300012,
["Hardened Azerite(Rank 2)"] = 298082,
["Anima of Life(Rank 2)"] = 300004,
-- Healer Essences
["The Ever-Rising Tide(Rank 2)"] = 299878,
["The Well of Existence(Rank 2)"] = 299935,
["Artifice of Time(Rank 2)"] = 299885,
["Seed of Eonar(Rank 2)"] = 299939,
["Transference(Rank 2)"] = 303474,
-- DPS Essences
["Reckless Force(Rank 2)"] = 299375,
["Purification Protocol(Rank 2)"] = 299343,
["Blood-Soaked(Rank 2)"] = 298274,
["Focused Energy(Rank 2)"] = 299335,
["Condensed Life-Force(Rank 2)"] = 299354,
-- Rank 3
-- Essences Used by All Roles
["Ancient Flame(Rank 3)"] = 299350,
["Lifeblood(Rank 3)"] = 299333,
["Reality Shift(Rank 3)"] = 302985,
["Strive for Perfection(Rank 3)"] = 299369,
["Lucid Dreams(Rank 3)"] = 299373,
["Strife(Rank 3)"] = 304123,
-- Tank Essences
["Stand Your Ground(Rank 3)"] = 299277,
["Null Barrier(Rank 3)"] = 300020,
["Sphere of Suppression(Rank 3)"] = 300013,
["Hardened Azerite(Rank 3)"] = 298083,
["Anima of Life(Rank 3)"] = 300005,
-- Healer Essences
["The Ever-Rising Tide(Rank 3)"] = 299879,
["The Well of Existence(Rank 3)"] = 299936,
["Artifice of Time(Rank 3)"] = 299887,
["Seed of Eonar(Rank 3)"] = 299940,
["Transference(Rank 3)"] = 303476,
-- DPS Essences
["Reckless Force(Rank 3)"] = 299377,
["Purification Protocol(Rank 3)"] = 299346,
["Blood-Soaked(Rank 3)"] = 298275,
["Focused Energy(Rank 3)"] = 299337,
["Condensed Life-Force(Rank 3)"] = 299357,
-- Rank 4 (same IDs as Rank 3)
-- Essences Used by All Roles
["Ancient Flame(Rank 4)"] = 299350,
["Lifeblood(Rank 4)"] = 299333,
["Reality Shift(Rank 4)"] = 302985,
["Strive for Perfection(Rank 4)"] = 299369,
["Lucid Dreams(Rank 4)"] = 299373,
["Strife(Rank 4)"] = 304123,
-- Tank Essences
["Stand Your Ground(Rank 4)"] = 299277,
["Null Barrier(Rank 4)"] = 300020,
["Sphere of Suppression(Rank 4)"] = 300013,
["Hardened Azerite(Rank 4)"] = 298083,
["Anima of Life(Rank 4)"] = 300005,
-- Healer Essences
["The Ever-Rising Tide(Rank 4)"] = 299879,
["The Well of Existence(Rank 4)"] = 299936,
["Artifice of Time(Rank 4)"] = 299887,
["Seed of Eonar(Rank 4)"] = 299940,
["Transference(Rank 4)"] = 303476,
-- DPS Essences
["Reckless Force(Rank 4)"] = 299377,
["Purification Protocol(Rank 4)"] = 299346,
["Blood-Soaked(Rank 4)"] = 298275,
["Focused Energy(Rank 4)"] = 299337,
["Condensed Life-Force(Rank 4)"] = 299357,
},
["Riding"] = {
["Draenor Pathfinder"] = 191645, -- One rank only -- Flying
["Apprentice Riding"] = 33388,
["Broken Isles Pathfinder(Rank 1)"] = 226342, -- +20% mounted speed
["Broken Isles Pathfinder(Rank 2)"] = 233368, -- Flying
["Broken Isles Pathfinder"] = 233368, -- Flying
["Expert Riding"] = 34090,
["Journeyman Riding"] = 33391,
["Artisan Riding"] = 34091,
["Master Riding"] = 90265,
["Battle for Azeroth Pathfinder(Rank 1)"] = 281576, -- +20% mounted speed
["Battle for Azeroth Pathfinder(Rank 2)"] = 278833, -- Flying
["Battle for Azeroth Pathfinder"] = 278833, -- Flying
},
["ZoneAbilities"] = {
-- Draenor
["Dragoon"] = 169605,
["Swift Recovery"] = 169608,
["Trading Pact"] = 170200,
["Upgrades"] = 170733,
["Runes of Power"] = 178777,
["Silver Dollar Club"] = 169606,
},
},
["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,
},
},
},
["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");
-- print(AddonName.. ": Will now check whether the GeneralTab Metadata needs updating.");
if not updateGeneralTabMetadata then
-- print(AddonName.. ": GeneralTab\'s Metadata does NOT need update.");
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.");
-- Actively-cast spells
-- print(AddonName.. ": type(METADATA_table) = ".. tostring(type(METADATA_table)));
-- print(AddonName.. ": type(generalTabName) = ".. tostring(type(generalTabName)));
-- print(AddonName.. ": type(METADATA_table[generalTabName]) = ".. tostring(type(METADATA_table[generalTabName])));
if charLevel > METADATA_table[generalTabName].dataSource.charLevel then
METADATA_table[generalTabName].dataSource.charLevel = charLevel;
if charLevel > METADATA_table[generalTabName].dataSource.charMaxLevel then
METADATA_table[generalTabName].dataSource.charMaxLevel = charLevel;
end
updateGeneralSpells = true;
end
if gameBuild > METADATA_table[generalTabName].dataSource.gameBuild then
METADATA_table[generalTabName].dataSource.gameBuild = gameBuild;
-- Highest charLevel stored upon the most recent gameBuild
METADATA_table[generalTabName].dataSource.charLevel = charLevel;
-- Highest charLevel ever stored is kept in [...].charMaxLevel
updateGeneralSpells = true;
end
if not METADATA_table[generalTabName].raceBuilds then
METADATA_table[generalTabName].raceBuilds = { [universalRaceName] = gameBuild, };
elseif (not METADATA_table[generalTabName].raceBuilds[universalRaceName]) or
(gameBuild > METADATA_table[generalTabName].raceBuilds[universalRaceName]) then
METADATA_table[generalTabName].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.");
-- print(AddonName.. ": Will now check whether the ".. universalClassName.. " Metadata needs updating.");
if not updateClassMetadata then
-- print(AddonName.. ": ".. universalClassName.. "\'s Metadata does NOT need update.");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": ".. universalClassName.. "\'s Metadata does NOT need update.");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateClassMetadata_func: END");
return;
end
-- print(AddonName.. ": ".. universalClassName.. "\'s Metadata DOES need update.");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": ".. universalClassName.. "\'s Metadata DOES need update.");
if charLevel > METADATA_table[universalClassName].dataSource.charLevel then
METADATA_table[universalClassName].dataSource.charLevel = charLevel;
if charLevel > METADATA_table[universalClassName].dataSource.charMaxLevel then
METADATA_table[universalClassName].dataSource.charMaxLevel = charLevel;
end
updateClassSpells = true;
end
if gameBuild > METADATA_table[universalClassName].dataSource.gameBuild then
METADATA_table[universalClassName].dataSource.gameBuild = gameBuild;
METADATA_table[universalClassName].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)
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updateTalentSpells_func: START");
if not updateClassSpells then -- Sanity check
-- print(AddonName.. ": Mo need to update the ".. universalClassName.. " PvE Talents.");
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.. ": PvE Talents: 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)
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePVPTalentSpells_func: START");
if not updateClassSpells then -- Sanity check
-- print(AddonName.. ": No need to update the ".. universalClassName.. " PvP Talents.");
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.. ": PvP Talents: 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
-- TODO Review this "NumberOfPVPTalentSlots" thing
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
if SN2SID_PASSIVES_table[universalClassName][locSpecName.."_PVPTalents"] then
SN2SID_PASSIVES_table[universalClassName][locSpecName.."_PVPTalents"][spellName] = spellID;
else
SN2SID_PASSIVES_table[universalClassName][locSpecName.."_PVPTalents"] = { [spellName] = spellID, };
end
else
if SN2SID_table[universalClassName][locSpecName.."_PVPTalents"] then
SN2SID_table[universalClassName][locSpecName.."_PVPTalents"][spellName] = spellID;
else
SN2SID_table[universalClassName][locSpecName.."_PVPTalents"] = { [spellName] = spellID, };
end
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
elseif spellSubName and strfind(spellSubName, "Azerite Essence") then
if not SN2SID_PASSIVES_table[generalTabName].AzeriteEssences then
SN2SID_PASSIVES_table[generalTabName].AzeriteEssences = { [spellName] = spellID };
else
SN2SID_PASSIVES_table[generalTabName].AzeriteEssences[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: 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
elseif spellSubName and strfind(spellSubName, "Azerite Essence") then
if not SN2SID_table[generalTabName].AzeriteEssences then
SN2SID_table[generalTabName].AzeriteEssences = { [spellName] = spellID };
else
SN2SID_table[generalTabName].AzeriteEssences[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
-- The Mechagnome Active Racials don't have the "Racial" subtext (WoW 8.3.0); thus we'll
-- the current spell name against the ones we hardcoded in.
elseif postUpdate_Spells2Add.General.Racials.Mechagnome[spellName] then
if not SN2SID_table[generalTabName].Racials.Mechagnome then
SN2SID_table[generalTabName].Racials.Mechagnome = { [spellName] = spellID };
else
SN2SID_table[generalTabName].Racials.Mechagnome[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));
-- Create an access to the info that will be fetched
delayedSpellsInfo_tbl["Id"..flyoutSpellID] = Spell:CreateFromSpellID(flyoutSpellID);
-- Actually get the info and use it to update our DB
delayedSpellsInfo_tbl["Id"..flyoutSpellID]:ContinueOnSpellLoad(function()
-- delayedSpellsInfo_tbl["Id"..flyoutSpellID]:ContinueOnSpellLoad(function(flyoutSpellID)
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedFlyoutSpellInfo[Id".. flyoutSpellID.."]:ContinueOnSpellLoad: START");
-- print(AddonName.. ": Will now get the previously delayed information about flyoutSpellID: ".. flyoutSpellID);
-- Although we should only need to update spellSubName, we'll fetch a new
-- spellName + spellID by now. Thus, we'll update those fields too.
flyoutSpellName = delayedSpellsInfo_tbl["Id"..flyoutSpellID]:GetSpellName();
flyoutSpellSubname = delayedSpellsInfo_tbl["Id"..flyoutSpellID]:GetSpellSubtext(); -- NEEDED
flyoutSpellID = delayedSpellsInfo_tbl["Id"..flyoutSpellID]:GetSpellID();
-- Use the values above to add the spell
addPolymorphOrHexFlyoutSpell_func(flyoutButtonName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID);
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedFlyoutSpellInfo[Id".. flyoutSpellID.."]:ContinueOnSpellLoad: END");
-- Discard the no longer used delayed callback
delayedSpellsInfo_tbl["Id"..flyoutSpellID] = nil;
end);
else
-- print(AddonName.. ": ".. tostring(flyoutSpellName).. " = ".. tostring(flyoutSpellID));
addPolymorphOrHexFlyoutSpell_func(flyoutButtonName, flyoutSpellName, flyoutSpellSubname, flyoutSpellID);
end
-- Add the default Polymorph(Sheep) and Hex(Frog) to the spell lists -- NOT WORKING!! TODO: Fix!
if universalClassName == "MAGE" then
-- In case the regualr spell hasn't been added to the DB yet, add it:
if not (SN2SID_table.MAGE.Arcane["Polymorph"] and SN2SID_table.MAGE.Fire["Polymorph"] and SN2SID_table.MAGE.Frost["Polymorph"]) then
print(AddonName.. ": Adding \'Polymorph\' to the list of spells.");
local _, _, _, _, _, _, quickSpellID = GetSpellInfo("Polymorph");
SN2SID_table.MAGE.Arcane["Polymorph"] = quickSpellID;
SN2SID_table.MAGE.Fire["Polymorph"] = quickSpellID;
SN2SID_table.MAGE.Frost["Polymorph"] = quickSpellID;
end
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
-- In case the regualr spell hasn't been added to the DB yet, add it:
if not (SN2SID_table.SHAMAN.Elemental["Hex"] and SN2SID_table.SHAMAN.Enhancement["Hex"] and SN2SID_table.SHAMAN.Restoration["Hex"]) then
print(AddonName.. ": Adding \'Hex\' to the list of spells.");
local _, _, _, _, _, _, quickSpellID = GetSpellInfo("Hex");
SN2SID_table.SHAMAN.Elemental["Hex"] = quickSpellID;
SN2SID_table.SHAMAN.Enhancement["Hex"] = quickSpellID;
SN2SID_table.SHAMAN.Restoration["Hex"] = quickSpellID;
end
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
-- Get rid of the STUB table member that was added upon its creation
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)
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
-- print(AddonName.. ": Will now update the GeneralTab spells.");
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].AzeriteEssences then
SN2SID_table[generalTabName].AzeriteEssences = {};
end
-- if not SN2SID_PASSIVES_table[generalTabName].AzeriteEssences then
-- SN2SID_PASSIVES_table[generalTabName].AzeriteEssences = {};
-- 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);
delayedSpellsInfo_tbl["Id"..spellID] = 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 safety.
--
-- ADENDA (from vague memory): :ContinueWithCancelOnSpellLoad() was causing some
-- problem (I can't remember what) and its removal had no ill effects.
--
-- 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:
delayedSpellsInfo_tbl["Id"..spellID]:ContinueOnSpellLoad(function()
-- delayedSpellsInfo_tbl["Id"..spellID]:ContinueOnSpellLoad(function(spellID)
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo[Id".. spellID.."]:ContinueOnSpellLoad: START");
-- print(AddonName.. ": Will now get the previously delayed information about spell ID: ".. spellID);
-- -- Although we should only need to update spellSubName, we'll fetch a new
-- spellName + spellID by now. Thus, we'll update those fields too.
spellName = delayedSpellsInfo_tbl["Id"..spellID]:GetSpellName();
spellSubName = delayedSpellsInfo_tbl["Id"..spellID]:GetSpellSubtext(); -- Mandatory
spellID = delayedSpellsInfo_tbl["Id"..spellID]:GetSpellID();
-- Use the values above to add the spell
addSpellbookSpellToGeneral_func(spellName, spellSubName, spellID);
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo[Id".. spellID.."]:ContinueOnSpellLoad: END");
-- Discard the no longer used delayed callback
delayedSpellsInfo_tbl["Id"..spellID] = nil;
end);
else
addSpellbookSpellToGeneral_func(spellName, spellSubName, spellID);
end
end
end
-- end
 
-- Class spells
-- if updateClassSpells then
-- print(AddonName.. ": Will now update the "..universalClassName .." spells.");
updateTalentSpells_func(ClassNumSpecs);
updatePVPTalentSpells_func(ClassNumSpecs);
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);
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 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
-- print(AddonName.. ": Add All Specs : ".. spellName);
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 not SN2SID_table[universalClassName].Pets["Tenacity"] then
SN2SID_table[universalClassName].Pets["Tenacity"] = { [spellName] = spellID, };
else
SN2SID_table[universalClassName].Pets["Tenacity"][spellName] = spellID;
end
if not SN2SID_table[universalClassName].Pets["Cunning"] then
SN2SID_table[universalClassName].Pets["Cunning"] = { [spellName] = spellID, };
else
SN2SID_table[universalClassName].Pets["Cunning"][spellName] = spellID;
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 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 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 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 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 not SN2SID_table[universalClassName].Pets["Ferocity"] then
SN2SID_table[universalClassName].Pets["Ferocity"] = { [spellName] = spellID, };
else
SN2SID_table[universalClassName].Pets["Ferocity"][spellName] = spellID;
end
end
elseif strfind(spellSubName, "Tenacity") then -- Tenacity
if isPassive then
-- print(AddonName.. ": Add Tenacity Passive : ".. spellName);
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 not SN2SID_table[universalClassName].Pets["Tenacity"] then
SN2SID_table[universalClassName].Pets["Tenacity"] = { [spellName] = spellID, };
else
SN2SID_table[universalClassName].Pets["Tenacity"][spellName] = spellID;
end
end
elseif strfind(spellSubName, "Cunning") then -- Cunning
if isPassive then
-- print(AddonName.. ": Add Cunning Passive : ".. spellName);
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 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
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Pet's family is n/a. Will not get any Pet spells.");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": updatePetSpellNames: END");
return; -- UNIT_PET fires two to three times when a new pet is summoned.
end
-- print(AddonName.. ": Pet Family = ".. tostring(petFamily));
 
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
 
local numPetSpells = HasPetSpells();
local _, isHunterPet = HasPetUI();
if isHunterPet then -- Hunter Pets, unlike all others, have specializations, thus 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 numPetSpells 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
for i = 1, numPetSpells do
-- 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
delayedSpellsInfo_tbl["Id"..spellID] = Spell:CreateFromSpellID(spellID);
-- Actually get the information and use it to update our database:
-- delayedSpellInfo:ContinueOnSpellLoad(function()
delayedSpellsInfo_tbl["Id"..spellID]:ContinueOnSpellLoad(function()
-- delayedSpellsInfo_tbl["Id"..spellID]:ContinueOnSpellLoad(function(spellID)
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo[Id".. spellID.."]:ContinueOnSpellLoad: START");
-- print(AddonName.. ": Will now get the previously delayed information about spell ID: ".. spellID);
-- Although we should only need to update spellSubName, we'll
-- get spellName and spellID too.
spellName = delayedSpellsInfo_tbl["Id"..spellID]:GetSpellName();
spellSubName = delayedSpellsInfo_tbl["Id"..spellID]:GetSpellSubtext(); -- Mandatory
spellID = delayedSpellsInfo_tbl["Id"..spellID]:GetSpellID();
addSpellbookPetSpell_func(spellName, spellSubName, spellID);
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": delayedSpellInfo[Id".. spellID.."]:ContinueOnSpellLoad: END");
-- Discard the no longer used delayed callback
delayedSpellsInfo_tbl["Id"..spellID] = nil;
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;
end
-- petHasSpellsConfirmed = true;
end
 
-- GetSpellBookItemName(SpellbookIndex, BOOKTYPE_PET) + GetSpellInfo(spellName) --
elseif numPetSpells 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
for i = 1, numPetSpells do
-- 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 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
-- until spellName == nil;
end
-- 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_func = function()
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": addSpellsPostUpdate_func: 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);
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 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_func: 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 {};
METADATA_table = AddonEnv.METAdata or METAdata or {};
-- print(AddonName.. ": Made local copies of addon's Saved Variables.");
 
-- tinsert(DEBUGmsgs[DBG_CurrentEvent], 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.. ": AddonEnv.METAdata = ".. tostring(AddonEnv.METAdata)); -- 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.. ": METAdata = ".. tostring(METAdata)); -- TableB
-- print(AddonName.. ": SN2SID_table = ".. tostring(SN2SID_table));-- TableA
-- print(AddonName.. ": SN2SID_PASSIVES_table = ".. tostring(SN2SID_PASSIVES_table)); -- TableB
-- print(AddonName.. ": DEBUGmsgs = ".. tostring(DEBUGmsgs)); -- TableC
-- print(AddonName.. ": METADATA_table = ".. tostring(METADATA_table)); -- TableD
-- tinsert(DEBUGmsgs[DBG_CurrentEvent], 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[DBG_CurrentEvent], 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[DBG_CurrentEvent], tostring(GetTime()).. ": Validated: curLocale");
local stubVal;
stubVal, universalRaceName = UnitRace("player");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Got: universalRaceName (no validation needed) = ".. universalRaceName);
-- Self-explanatory:
local _, gameBuild = GetBuildInfo();
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Got: gameBuild");
-- For some reason, the variable gameBuild is being saved as a string; convert to number:
gameBuild = tonumber(gameBuild);
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Validated that gameBuild is a number. gameBuild = ".. gameBuild.. ": Done.");
local charLevel = UnitLevel("player");
tinsert(DEBUGmsgs[DBG_CurrentEvent], 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[DBG_CurrentEvent], tostring(GetTime()).. ": Got: generalTabName (no validation needed) = ".. generalTabName);
-- Class stuff --
stubVal, universalClassName = UnitClass("player"); -- Locale-independent Class name
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Got: universalClassName (no validation needed) = ".. universalClassName);
local ClassNumSpecs = GetNumSpecializations(false, false); -- Number of Specialisations
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Got: ClassNumSpecs (no validation needed) = ".. ClassNumSpecs);
-- Ordered list of Class specs' IDs and Names -- Do we still use this?
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Order list of Class specs' IDs and Names: START");
local specID, specName = GetSpecializationInfo(1);
tinsert(DEBUGmsgs[DBG_CurrentEvent], 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("Local copy of saved variables is missing.");
end
if not SN2SID_PASSIVES_table then -- sanity check
error("Local copy of saved variables is missing.");
end
if not DEBUGmsgs then -- sanity check
error("Local copy of saved variables is missing.");
end
if not METADATA_table then -- sanity check
error("Local copy of saved variables is missing.");
end
 
--
-- If needed, create and populate the Metadata subtables; --
-- Flag spell-lists for update if applicable --
--
-- General tab skeleton + dataSource + raceBuilds
if not SN2SID_table[generalTabName] then
SN2SID_table[generalTabName] = {};
end
if not SN2SID_PASSIVES_table[generalTabName] then
SN2SID_PASSIVES_table[generalTabName] = {};
end
if not METADATA_table[generalTabName] then
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource: START");
-- print(AddonName.. ": Will now create the ".. generalTabName.. " dataSource.");
METADATA_table[generalTabName] = {
dataSource = {
clientLocale = curLocale, -- Currently always enUS
gameBuild = gameBuild,
charLevel = charLevel,
charMaxLevel = charLevel,
},
};
METADATA_table[generalTabName].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[DBG_CurrentEvent], tostring(GetTime()).. ": Create the ".. generalTabName.. " dataSource: 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[DBG_CurrentEvent], tostring(GetTime()).. ": Updated the ".. generalTabName.. " Metadata \(or not\!\) for both Active and Passive spells.");
 
-- Class spells' skeleton + dataSource (class Specs will be handled afterwards)
if not SN2SID_table[universalClassName] then
-- print(AddonName.. ": Will now create the ".. universalClassName.. "'s table for Active spells.");
SN2SID_table[universalClassName] = {};
end
if not SN2SID_PASSIVES_table[universalClassName] then
-- print(AddonName.. ": Will now create the ".. universalClassName.. "'s table for Passive spells.");
SN2SID_PASSIVES_table[universalClassName] = {};
end
if not METADATA_table[universalClassName] then
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource: START");
METADATA_table[universalClassName] = {};
METADATA_table[universalClassName].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[DBG_CurrentEvent], tostring(GetTime()).. ": Create the ".. universalClassName.. " dataSource: 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 dataSource
updateClassMetadata_func(curLocale, gameBuild, charLevel);
tinsert(DEBUGmsgs[DBG_CurrentEvent], 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 METADATA_table[universalClassName].Specs then
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' tables: START");
-- print(AddonName.. ": Will now create the ".. universalClassName.. "'s \'Specs\' tables.");
for i = 1, ClassNumSpecs do
local specID, specName = GetSpecializationInfo(i);
-- print(AddonName.. ": ".. i.. " = ".. specName.. " = ".. specID); -- For reference
if not METADATA_table[universalClassName].Specs then
METADATA_table[universalClassName].Specs = { [specName] = specID }; -- Reference
elseif not METADATA_table[universalClassName].Specs[i] then
METADATA_table[universalClassName].Specs[specName] = specID; -- Reference
end
SN2SID_table[universalClassName][specName] = {}; -- For "[SpellName] = SpellID"
SN2SID_PASSIVES_table[universalClassName][specName] = {}; -- For "[SpellName] = SpellID"
end
updateClassSpells = true; -- Do populate the actual list of spells.
-- print(AddonName.. ": ".. universalClassName.. "'s \'Specs\' tables created.");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Create the ".. universalClassName.. " \'Specs\' tables: END");
end
 
-- Update General (always ATM) and Class SpellNames2SIDs (both Actives and Passives) --
-- print(AddonName.. ": Will update ".. universalClassName.. " spells in its ".. ClassNumSpecs.. " Specs.");
updateGeneralSpells = true;
updateClassSpells = true;
updateSpellbookSpells_func(ClassNumSpecs);
-- print(AddonName.. ": Updated ".. universalClassName.. " spells in its ".. ClassNumSpecs.. " Specs.");
-- 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".
-- Adenda @WoW 8.1.5: For some reason, UNIT_PET seems to not be firing on PLAYER_LOGIN anymore
-- (or some other borkness), so we'll try and do a quick check here:
if UnitExists("pet") then
-- print(AddonName.. ": Will update ".. universalClassName.. " Pet spells.");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Get Pet spells: START");
updatePetSpellNames();
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Get Pet spells: END");
-- print(AddonName.. ": Updated ".. universalClassName.. " Pet spells.");
end
 
 
-- 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", }
-- print(AddonName.. ": ".. tostring(GetTime()).. ": "..DBG_CurrentEvent .. ": START");
-- updateGeneralSpells = true; -- unneeded, placeholder for future version
updateClassSpells = true;
updateSpellbookSpells_func(ClassNumSpecs);
tinsert(DEBUGmsgs["PLAYER_TALENT_UPDATE"], tostring(GetTime()).. ": PLAYER_TALENT_UPDATE: END");
-- print(AddonName.. ": ".. tostring(GetTime()).. ": "..DBG_CurrentEvent .. ": END");
end
 
function SN2SID_events:PLAYER_LEVEL_UP(self, ...)
DBG_CurrentEvent = "PLAYER_LEVEL_UP";
DEBUGmsgs["PLAYER_LEVEL_UP"] = { tostring(GetTime()).. ": PLAYER_LEVEL_UP: START", }
-- print(AddonName.. ": ".. tostring(GetTime()).. ": "..DBG_CurrentEvent .. ": 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.
updateGeneralTabMetadata_func(curLocale, gameBuild, charLevel);
updateClassMetadata_func(curLocale, gameBuild, charLevel);
updateSpellbookSpells_func(ClassNumSpecs);
tinsert(DEBUGmsgs["PLAYER_LEVEL_UP"], tostring(GetTime()).. ": PLAYER_LEVEL_UP: END");
-- print(AddonName.. ": ".. tostring(GetTime()).. ": "..DBG_CurrentEvent .. ": END");
end
 
-- Update pets' existence and spells when one comes up for "player"
-- NB: Fires on 'Pet Dismiss' and 'Summon Pet' button clicks.
-- 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[DBG_CurrentEvent] = { tostring(GetTime()).. ": UNIT_PET: START", };
updatePetSpellNames();
tinsert(DEBUGmsgs["UNIT_PET"], tostring(GetTime()).. ": UNIT_PET: END");
end
 
function SN2SID_events:PLAYER_LOGOUT(self)
-- print(AddonName.. ": ".. tostring(GetTime()).. ": "..DBG_CurrentEvent .. ": START"); -- Meh!
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);
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_func();
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, and METADATA_table, to SavedVariables: START");
AddonEnv.SpellNamesAndIDs = SN2SID_table;
SpellNamesAndIDs = SN2SID_table;
AddonEnv.SpellNamesAndIDs_PASSIVES = SN2SID_PASSIVES_table;
SpellNamesAndIDs_PASSIVES = SN2SID_PASSIVES_table;
AddonEnv.METAdata = METADATA_table;
METAdata = METADATA_table;
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy session\'s Active and Passive Spells' tables, and METADATA_table, to SavedVariables: END");
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy the DEBUG messages to SavedVariables: START");
AddonEnv.DEBUG_messages = DEBUGmsgs;
DEBUG_messages = DEBUGmsgs;
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": Copy the DEBUG messages to SavedVariables: END");
-- print(AddonName.. ": ".. tostring(GetTime()).. ": "..DBG_CurrentEvent .. ": END"); -- Meh!
tinsert(DEBUGmsgs["PLAYER_LOGOUT"], tostring(GetTime()).. ": PLAYER_LOGOUT: END");
end
 
-- Unregister the event (handler) in which we are now running, to free up RAM
SN2SID_frame:UnregisterEvent("PLAYER_LOGIN");
tinsert(DEBUGmsgs[DBG_CurrentEvent], tostring(GetTime()).. ": Unregistered Event: ".. DBG_CurrentEvent);
-- Set the post-PLAYER_LOGIN event-handlers and Register the respective events
SN2SID_frame:SetScript("OnEvent", function(self, event, ...)
SN2SID_events[event](self, ...);
end);
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[DBG_CurrentEvent], tostring(GetTime()).. ": Registered Event: ".. k);
end
tinsert(DEBUGmsgs[DBG_CurrentEvent], (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)
-- print(AddonName.. ": Event ".. event.. " fired.");
DBG_CurrentEvent = event;
DEBUGmsgs = AddonEnv.DEBUG_messages or DEBUG_messages or {};
if not DEBUGmsgs then
DEBUGmsgs = {
[DBG_CurrentEvent] = {
tostring(GetTime()).. ": ".. DBG_CurrentEvent.. ": START",
tostring(GetTime()).. ": Will startup in 5 seconds time.",
},
};
else
DEBUGmsgs[DBG_CurrentEvent] = {
tostring(GetTime()).. ": ".. DBG_CurrentEvent.. ": START",
tostring(GetTime()).. ": Will startup in 5 seconds time.",
};
end
C_Timer.After(5, lsn2sidpStartup);
-- print(AddonName.. ": Event ".. event.. " handled.");
end);
tags/LibSpellName2SID-Populator-1.1.11b/LibSpellName2SID-1.1-Populator.toc New file
0,0 → 1,11
## Interface: 80300
## Title: LibSpellName2SID-1.1: Populator (DEV)
## Notes: Get all spells from a character and save them to file.
## Author: aallkkaa
## Version: 1.1.11b
## SavedVariables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES, DEBUG_messages, METAdata
## DefaultState: disabled
## X-Category: Development
## X-License: MIT
 
LibSpellName2SID-1.1-Populator.lua
trunk/LibSpellName2SID-1.1-Populator/LibSpellName2SID-1.1-Populator.toc
2,7 → 2,7
## Title: LibSpellName2SID-1.1: Populator (DEV)
## Notes: Get all spells from a character and save them to file.
## Author: aallkkaa
## Version: 1.1.11
## Version: 1.1.11b
## SavedVariables: SpellNamesAndIDs, SpellNamesAndIDs_PASSIVES, DEBUG_messages, METAdata
## DefaultState: disabled
## X-Category: Development