/
spells[globalID] = true |
end |
end |
if not self.saved.autoAttack then |
-- Treat Auto Shot, Auto Attack and Shoot (Wand) as though already on an action bar |
spells[self.autoAttack] = true |
spells[self.autoShot] = true |
spells[self.shootWand] = true |
end |
for tab = 1, 2 do |
local _, _, start, count = GetSpellTabInfo(tab) -- the current spec |
for i = start + 1, start + count do |
FIXED, MUST VERIFY "Asphyxiate", a talent override, has the wrong name, "Strangulate" in the LA popup. |
FIXED change remaining instances of .globalID, .specID and .slot to ._gid, ._sid and ._slot respectively |
FIXED fix remaining instances of .globalID, .specID and .slot to ._gid, ._sid and ._slot respectively |
Flyouts: Tricky cases |
Don't have flyout, do have all flyout spells |
self:RegisterEvent("PLAYER_ENTERING_WORLD") |
end |
function LA:PLAYER_LEVEL_UP() |
--self:PrintPending() |
self:PrintPending() |
end |
function LA:PLAYER_LOGIN() |
self:UpdateSpellBook() |
self.closeButton:Enable() |
self:ProcessQueue() |
end |
function LA:PLAYER_TALENT_UPDATE() |
if self.state.untalenting then |
self.state.untalenting = false |
self:UnregisterEvent("ACTIONBAR_SLOT_CHANGED") |
self:UnregisterEvent("PLAYER_TALENT_UPDATE") |
self:UnregisterEvent("UI_ERROR_MESSAGE") |
--self:PrintPending() |
self:PrintPending() |
elseif self.pendingTalentCount > 0 then |
self.pendingTalentCount = self.pendingTalentCount - 1 |
if self.pendingTalentCount <= 0 then |
--self:PrintPending() |
self:PrintPending() |
self:UnregisterEvent("PLAYER_TALENT_UPDATE") |
end |
elseif self.state.learning then |
self.state.learning = false |
self:UnregisterEvent("PLAYER_TALENT_UPDATE") |
--self:PrintPending() |
self:PrintPending() |
end |
end |
function LA:SPELLS_CHANGED() |
self:UpgradeIgnoreList() |
--PANDARIA |
if not self.companionsReady then |
self:UpdateCompanions() |
end |
--]] |
if self.numSpells > 0 then |
]] |
if self.numSpells > 0 then |
if self:DiffSpellBook() > 0 then |
if self.pendingBuyCount > 0 then |
self.pendingBuyCount = self.pendingBuyCount - 1 |
--if self.pendingBuyCount <= 0 then |
--self:PrintPending() |
--end |
if self.pendingBuyCount <= 0 then |
self:PrintPending() |
end |
end |
end |
end |
end |
end |
]] |
-- Patch 6.2.0 -- self:PrintPending() |
self:PrintPending() |
end |
end |
function LA:UI_ERROR_MESSAGE() |
bottom-up |
A Spell is an object with slot obj._slot, Global ID obj._gID, |
spec-specific ID obj._sid and getter methods Name(), |
A Spell is an object with data globalID and getter methods Name(), |
Slot(), Status(), Link(), Known(), etc |
The metatable contains the actual methods, when attempting to index |
the object, the methods are called on the object |
spell.Name -> meta.Name(spell) -> GetSpellBookItemName(spell.Slot) |
As is normal for Lua OOP, the metatable contains the methods. Attempting |
to index an instance object retrieves any missing entries from the metatable. |
The methods are then called on the object. |
spell.Name -> meta.Name(spell) -> GetSpellBookItemName(spell.Slot) -> |
GetSpellBookItemName( |
BookID is an object that instantiates a new Spell object whenever a |
nonexistent index is accessed |
BookID[n] -> bookIDMeta.__index (t, n) -> setmetatable({ globalID = g }, SpellMeta) |
return spell |
elseif "FLYOUT" == gType then |
return LA.Spell.Flyout[gID] |
elseif nil == gType then |
return nil |
else |
error("LearningAid.Spell.Book: Type of spellbook slot #"..tostring(index).." ("..tostring(gType)..") is not known", 2) |
end |
return SpellKnown(spell._gid) |
end |
function spellMeta.Status(spell) |
if spell.Slot then |
return SpellBookItemInfo(spell.Slot, BOOKTYPE_SPELL) |
end |
local slot = spell.Slot |
assert(spell.Slot, LA.name..": Spell #"..spell._gid.." slot unknown in Spell.Status.") |
return SpellBookItemInfo(slot, BOOKTYPE_SPELL) |
end |
function spellMeta.ID(spell) |
return spell._gid |
function spellMeta.Slot(spell) |
--local name = spell.Name |
--local infoName = spell.Info.name |
--local globalID = spell._gid |
local globalID = spell._gid |
-- use rawget because _slot might be nil, which would call metatable._slot as a method and fail |
local oldSlot = rawget(spell, "_slot") |
local newSlot = SpellBookSlotBySpellID(spell._gid) |
spell._slot = newSlot |
if newSlot ~= oldSlot then |
-- tostring to guard against nil values |
LA:DebugPrint("Spell ".. spell._gid .." slot changed from ".. tostring(oldSlot).." to ".. tostring(newSlot)) |
local slot = SpellBookSlotBySpellID(globalID) |
if slot then |
if slot ~= oldSlot then |
-- tostring to guard against nil values |
LA:DebugPrint("Spell ".. globalID.. " slot changed from ".. tostring(oldSlot).. " to ".. tostring(slot)) |
end |
spell._slot = slot |
return slot |
end |
return newSlot |
return oldSlot |
end |
function spellMeta.Link(spell) |
return SpellLink(spell._gid) or "" |
return SpellPassive(spell._gid) |
end |
function spellMeta:Pickup() |
return PickupSpell(self._gid) |
PickupSpell(self._gid) |
end |
function spellMeta.Texture(spell) |
return GetSpellTexture(spell._gid) |
iconTexture:SetTexture(texture) |
spellString:SetText(spellName) |
subSpellString:SetText(subSpellName) |
subSpellString:SetText(spellSubName) |
if ( spellSubName ~= "" ) then |
spellString:SetPoint("LEFT", button, "RIGHT", 4, 4) |
else |
titleHeight = 40, -- pixels |
frameWidth = 200, -- pixels |
framePadding = 10, -- pixels |
verticalSpacing = 13, -- pixels |
verticalSpacing = 5, -- pixels |
horizontalSpacing = 153, -- pixels |
buttonSize = 37, -- pixels |
width = 1, -- button columns |
-- add tradeskill learning stuff here |
}, |
defaults = { -- default savedvariables contents |
macros = true, |
totem = true, |
enabled = true, |
restoreActions = true, |
filterSpam = 1, -- FILTER_SUMMARIZE |
debugFlags = { }, |
ignore = { }, |
-- Search options |
macros = true, -- Search inside macro bodies |
totem = true, -- Search for totem spells (Shaman only) |
autoAttack = false, -- Search for Auto Attack, Auto Shot and Shoot |
shapeshift = true -- Search for shapeshifts, stances, auras, presences, etc. |
ignore = { } |
}, |
menuHideDelay = 5, -- seconds |
pendingBuyCount = 0, |
activateSecondarySpec = 63644, -- global spellID |
autoAttack = 6603, -- global spellID |
autoShot = 75, -- global spellID |
shootWand = 5019, -- global spellID |
racialSpell = 20549, -- War Stomp (Tauren). Used to determine the subName text for racials. |
racialPassiveSpell = 20550, -- Endurance (Tauren). Used to determine the subName text for racial passives. |
ridingSpells = { |
-- width = "full", |
order = 1 |
}, |
autoattack = { |
name = self:GetText("findAutoAttack"), |
desc = self:GetText("findAutoAttackHelp"), |
type = "toggle", |
set = function(info, val) self.saved.autoAttack = val end, |
get = function(info) return self.saved.autoAttack end, |
width = "full", |
order = 2 |
}, |
shapeshift = { |
name = self:GetText("findShapeshift"), |
desc = self:GetText("findShapeshiftHelp"), |
desc = "The Kitchen Sink", |
type = "execute", |
func = function () |
local spec, icon, first, count = GetSpellTabInfo(2) -- main spec |
local spell |
for i = 1, first + count do |
spell = self.Spell.Book[i] |
if spell and ("SPELL" == spell.Status) and spell.Known and (not spell.Passive) then |
self:AddButton(spell) |
end |
local i = 1 |
local spellName = GetSpellBookItemName(i, BOOKTYPE_SPELL) |
while spellName do |
self:AddButton(self.Spell.Book[i]) |
i = i + 1 |
spellName = GetSpellBookItemName(i, BOOKTYPE_SPELL) |
end |
end |
} |
self:DebugPrint("ConfirmTalentWipe") |
self:SaveActionBars() |
self.state.untalenting = true |
--self.spellsUnlearned = {} |
self:RegisterEvent("ACTIONBAR_SLOT_CHANGED", "OnEvent") |
--self:RegisterEvent("PLAYER_TALENT_UPDATE", "OnEvent") |
self:RegisterEvent("PLAYER_TALENT_UPDATE", "OnEvent") |
-- self:RegisterEvent("UI_ERROR_MESSAGE", "OnEvent") |
end) |
--[[ PANDARIA |
]]-- TODO FIXME Rewrite entire talent handling code FIXME TODO -- |
self:RegisterChatCommand("la", "AceSlashCommand") |
self:RegisterChatCommand("learningaid", "AceSlashCommand") |
--self:SetEnabledState(self.saved.enabled) |
--self.saved.enabled = true |
--self:DebugPrint("OnEnable()") |
local baseEvents = { |
"ACTIVE_TALENT_GROUP_CHANGED", |
"ADDON_LOADED", |
-- DRAENOR 6.2 -- "CHAT_MSG_SYSTEM", |
-- PANDARIA -- "COMPANION_LEARNED", |
-- PANDARIA -- "COMPANION_UPDATE", |
"PET_TALENT_UPDATE", |
"PLAYER_LEAVING_WORLD", |
"PLAYER_LEVEL_UP", |
"PLAYER_LOGIN", |
"PLAYER_LOGOUT", |
-- MOP -- "PLAYER_GUILD_UPDATE", |
"PLAYER_REGEN_DISABLED", |
"PLAYER_REGEN_ENABLED", |
-- "SPELLS_CHANGED", -- wait until PLAYER_LOGIN |
"UNIT_SPELLCAST_START", |
"UI_SCALE_CHANGED", |
-- "UPDATE_BINDINGS", -- PANDARIA -- not needed because of companion/mount removal |
"VARIABLES_LOADED" |
--[[ |
"CURRENT_SPELL_CAST_CHANGED", |
"UNIT_SPELLCAST_SUCCEEDED" |
--]] |
} |
for i, event in ipairs(baseEvents) do |
self:RegisterEvent(event, "OnEvent") |
end |
--if private.logAllEvents then |
-- self.frame:RegisterAllEvents() |
--else |
for i, event in ipairs(baseEvents) do |
self:RegisterEvent(event, "OnEvent") |
end |
--end |
--self:UpdateSpellBook() |
--PANDARIA |
--self:UpdateCompanions() |
self:DiffActionBars() |
self:SaveActionBars() |
if self.saved.filterSpam ~= LA.FILTER_SHOW_ALL then |
self:DebugPrint("Initially adding chat filter for CHAT_MSG_SYSTEM") |
ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM", private.spellSpamFilter) |
end |
if self.saved.locked then |
self.menuTable[1].text = self:GetText("unlockPosition") |
else |
self.frame:SetFrameStrata(self.saved.frameStrata) |
end |
end |
--[[ No longer needed as of patch 6.2.0! |
-- this is a function |
function private.spellSpamFilter(...) return LA:spellSpamFilter(...) end |
-- this is a method |
function LA:spellSpamFilter(chatFrame, event, message, ...) |
-- local spell -- unused |
local patterns = self.patterns |
if (self.saved.filterSpam ~= self.FILTER_SHOW_ALL) and ( |
--( |
--self.state.untalenting or |
--self.state.retalenting or |
--(self.pendingTalentCount > 0) or |
--(self.saved.filterSpam == self.FILTER_SHOW_NONE) or |
--self.state.learning or |
-- self.petLearning or |
--(self.pendingBuyCount > 0) |
--) and ( |
string.match(message, patterns.learnSpell) or |
string.match(message, patterns.learnAbility) or |
string.match(message, patterns.learnPassive) or |
string.match(message, patterns.unlearnSpell) or |
-- ) |
--) or |
string.match(message, patterns.petLearnAbility) or |
string.match(message, patterns.petLearnSpell) or |
string.match(message, patterns.petUnlearnSpell) |
) then |
self:DebugPrint("Suppressing message") |
return true -- do not display the message |
else |
self:DebugPrint("Allowing message") |
return false, message, ... -- pass the message along |
end |
end |
--]] |
function LA:GetText(id, ...) |
if not id then |
if self.DebugPrint then |
trainAllPopup = "Train all available skills for", |
frameStrata = "Frame Strata", |
frameStrataHelp = "Adjust what frames Learning Aid appears above and below. Only change this if you have problems with frames overlapping each other.", |
advanced = "Advanced settings", |
-- Strings added in 1.12 |
findAutoAttack = "Find Auto Attack", |
findAutoAttackHelp = "If enabled, Find Missing Abilities will search for Auto Attack, Auto Shot and Shoot." |
advanced = "Advanced settings" |
} |
# 1.12b3 |
Updated TOC to 60200 for patch 6.2.0. |
Added "Ignore Auto Attack" option. |
Removed more dead Spam Filter code that was causing errors. |
# 1.12b2 |
Updated TOC to 60100 for patch 6.1.0. |
Fixed some global pollution found with Globe (https://www.townlong-yak.com/globe/). |
Added checks for spells like Flying Serpent Kick that change ID on the fly. |
Added initial visible support for action bar copy and paste. |
Added support for flyouts to action bar copy and paste. |
Added support for dynamic shapeshift bar numbering to action bar copy and paste. |
Added named bar clipboards to action bar copy and paste, replacing the single implicit clipboard. |
# 1.12b1 |
Update TOC for Warlords of Draenor pre-patch 6.0.2 |