AuctioneerSuite/Enchantrix/EnxAutoDisenchant.lua
2026-04-13 17:48:13 -04:00

722 lines
24 KiB
Lua

--[[
Enchantrix Addon for World of Warcraft(tm).
Version: 5.9.4961 (WhackyWallaby)
Revision: $Id: EnxAutoDisenchant.lua 4933 2010-10-13 17:16:14Z Nechckn $
URL: http://enchantrix.org/
Automatic disenchant scanner.
License:
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program(see GPL.txt); if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Note:
This AddOn's source code is specifically designed to work with
World of Warcraft's interpreted AddOn system.
You have an implicit license to use this AddOn with these facilities
since that is its designated purpose as per:
http://www.fsf.org/licensing/licenses/gpl-faq.html#InterpreterIncompat
]]
Enchantrix_RegisterRevision("$URL: http://svn.norganna.org/auctioneer/branches/5.9/Enchantrix/EnxAutoDisenchant.lua $", "$Rev: 4933 $")
local auto_de_session_ignore_list = {}
local auto_de_frame
local auto_de_prompt
local showPrompt
local hidePrompt
local clearPrompt
local auto_de_tooltip = LibStub("nTipHelper:1")
--------------------------------------------------------------------------------
-- Debug stuff
local DebugLib = LibStub("DebugLib")
local debug, assert
if DebugLib then
debug, assert = DebugLib("Enchantrix")
else
function debug() end
assert = debug
end
local function debugSpam(...)
-- local message = debug:Dump(...)
-- local r, g, b = 0, 0.75, 1
-- _G["ChatFrame1"]:AddMessage("AutoDe: " .. message, r, g, b)
end
local function eventSpam(...)
-- local message = debug:Dump(...)
-- debugSpam("Event: " .. message)
end
--------------------------------------------------------------------------------
-- Item ignore list and utility functions
local function itemStringFromLink(link)
local _, _, itemString = string.find(link, "^|c%x+|H(.+)|h%[.+%]")
return itemString
end
-- remove the uniqueID and viewer level from the link
-- this needs to be updated whenever the link format changes
local function genericizeItemLink(link)
-- strip out unique id
local _, _, head, tail = string.find(link, "^(|c%x+|H.+:)[-%d]+:%d+(|h.+)")
return head .. "0:0" .. tail
end
local function ignoreItemPermanent(link)
local genericLink = genericizeItemLink(link)
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeIgnorePermanent"):format(genericLink))
AutoDisenchantIgnoreList[genericLink] = true
end
local function ignoreItemSession(link, silent)
local genericLink = genericizeItemLink(link)
if not silent then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeIgnoreSession"):format(genericLink))
end
auto_de_session_ignore_list[genericLink] = true
end
local function isItemIgnored(link)
local genericLink = genericizeItemLink(link)
return auto_de_session_ignore_list[genericLink] or AutoDisenchantIgnoreList[genericLink]
end
-- check item quality and reason for purchase (if BeanCounter is installed)
local function isAutoDisenchantAllowed(link, count)
local _, _, quality, _ = GetItemInfo(link)
if (quality == 3) and (not Enchantrix.Settings.GetSetting('AutoDeRareItems')) then
return false
end
if (quality == 4) and (not Enchantrix.Settings.GetSetting('AutoDeEpicItems')) then
return false
end
-- this WILL NOT WORK for milling or prospecting
-- because changing the stack size in any way will change the reason returned by beancounter
if Enchantrix.Settings.GetSetting('AutoDeOnlyIfBoughtForDE') then
if (BeanCounter and BeanCounter.API) then
local reason = BeanCounter.API.getBidReason(link, count)
if (reason == "Disenchant" or reason == "EnchantMats") then
return true;
else
return false;
end
else
-- tell the user that beancounter is required
Enchantrix.Util.ChatPrint(_ENCH("BeanCounterRequired"))
Enchantrix.Settings.SetSetting('AutoDeOnlyIfBoughtForDE', false)
end
end
return true
end
local function nameFromIgnoreListItem(item)
local _, _, name = string.find(item, "%[(.+)%]")
return name
end
--------------------------------------------------------------------------------
-- Main logic
local moduleState
local function setState(newState)
if newState ~= state then
debugSpam("State: " .. newState)
moduleState = newState
end
end
-- declared local at top
local function isState(state)
return moduleState == state
end
local function getDisenchantOrProspectValue(link, count)
local _, _, quality, level = GetItemInfo(link)
if not (quality and level) then return end
if quality >= 2 then
local enchSkillRequired = Enchantrix.Util.DisenchantSkillRequiredForItemLevel(level, quality)
if enchSkillRequired and Enchantrix.Util.GetUserEnchantingSkill() >= enchSkillRequired then
local hsp, median, baseline, valFive = Enchantrix.Storage.GetItemDisenchantTotals(link)
if (not hsp) or (hsp == 0) then
-- what to do when Auc4 isn't loaded, but Auc5 is
-- or when you have no data for mat prices
if valFive and valFive > 0 then
hsp = valFive
else
hsp = baseline
end
end
if hsp and hsp > 0 then
return hsp, _ENCH('ArgSpellname')
end
end
end
-- some quality 2 ores are now prospectable
if count >= 5 then
-- TODO - ccox - these could share some code
local jcSkillRequired = Enchantrix.Util.JewelCraftSkillRequiredForItem(link)
if jcSkillRequired and Enchantrix.Util.GetUserJewelCraftingSkill() >= jcSkillRequired then
local prospect = Enchantrix.Storage.GetItemProspects(link)
if prospect then
local prospectValue = 0
for result, yield in pairs(prospect) do
local hsp, median, baseline, valFive = Enchantrix.Util.GetReagentPrice(result)
if (not hsp) or (hsp == 0) then
-- what to do when Auc4 isn't loaded, but Auc5 is
-- or when you have no data for mat prices
if valFive and valFive > 0 then
hsp = valFive
else
hsp = baseline
end
end
local value = (hsp or 0) * yield
prospectValue = prospectValue + value
end
return prospectValue, _ENCH('ArgSpellProspectingName')
end
end
local inscriptionSkillRequired = Enchantrix.Util.InscriptionSkillRequiredForItem(link)
if inscriptionSkillRequired and Enchantrix.Util.GetUserInscriptionSkill() >= inscriptionSkillRequired then
local milling = Enchantrix.Storage.GetItemMilling(link)
if milling then
local millingValue = 0
for result, yield in pairs(milling) do
local hsp, median, baseline, valFive = Enchantrix.Util.GetReagentPrice(result)
if (not hsp) or (hsp == 0) then
-- what to do when Auc4 isn't loaded, but Auc5 is
-- or when you have no data for mat prices
if valFive and valFive > 0 then
hsp = valFive
else
hsp = baseline
end
end
local value = (hsp or 0) * yield
millingValue = millingValue + value
end
return millingValue, _ENCH('ArgSpellMillingName')
end
end
end
end
-- check one bag (to save time when we know something moved in just this bag)
local function findItemInOneBag(bag, findLink)
for slot = 1, GetContainerNumSlots(bag) do
local _, count = GetContainerItemInfo(bag, slot)
local link = GetContainerItemLink(bag, slot)
if link and (not findLink or link == findLink) then
if not findLink and link == auto_de_prompt.link and bag == auto_de_prompt.bag
and slot == auto_de_prompt.slot and count == auto_de_prompt.count then
-- items sometimes linger after they've been disenchanted and looted
debugSpam("Skipping zombie item " .. link)
else
if (not isItemIgnored(link)) and isAutoDisenchantAllowed(link, count) then
local value, spell = getDisenchantOrProspectValue(link, count)
if value and value > 0 then
return link, bag, slot, value, spell
end
end
end
end
end
end
-- check all bags for disenchantable items
local function findItemInBags(findLink)
debugSpam("scanning bags")
for bag = 0, 4 do
local link, bag, slot, value, spell = findItemInOneBag(bag, findLink)
if (spell) then
return link, bag, slot, value, spell
end
end
end
local function beginScan(bag)
setState("scan")
-- do not scan while in combat
if UnitAffectingCombat("player") then
debugSpam("aborting scan during combat")
return
end
hidePrompt() -- we can't hide the UI during combat
local link, outBag, slot, value, spell
if (bag and bag >= 0 and bag <= 4) then -- exclude bank bags, we can't DE from the bank
link, outBag, slot, value, spell = findItemInOneBag(bag)
else
link, outBag, slot, value, spell = findItemInBags()
end
if link then
-- prompt for disenchant
setState("prompt")
showPrompt(link, outBag, slot, value, spell)
end
end
local function onEvent(...)
if isState("sleep") or isState("disabled") then return end
local _, event, arg1, arg2, arg3, arg4 = ...;
if event == "LOOT_OPENED" then
if isState("loot_wait") then
-- loot window opened - grab the spoils
eventSpam(...)
for slot = 1, GetNumLootItems() do
LootSlot(slot)
end
setState("loot")
else
-- see if the user wants to auto-loot their manual disenchants
if (Enchantrix.Settings.GetSetting('autoLootDE')) then
eventSpam(...)
-- make sure all results are DE/prospect/milling results
for slot = 1, GetNumLootItems() do
if (not LootSlotIsItem(slot)) then return end
local link = GetLootSlotLink(slot)
local _, itemID = auto_de_tooltip:DecodeLink(link)
if (not itemID) then return end
if ( not
(Enchantrix.Constants.ReverseDisenchantLevelList[itemID]
or Enchantrix.Constants.ReverseProspectingSources[itemID]
or Enchantrix.Constants.ReversePigmentList[itemID])) then
--eventSpam("item "..itemID.." not in our lists")
return -- this is not a DE,prospect, or milling result
end
end
for slot = 1, GetNumLootItems() do
LootSlot(slot)
end
end
end
elseif event == "LOOT_CLOSED" then
if isState("loot") then
-- looting done - continue scanning
eventSpam(...)
beginScan()
end
elseif event == "UNIT_SPELLCAST_SENT" then
if isState("prompt") and arg1 == "player" and arg2 == auto_de_prompt.Yes:GetAttribute("spell") then
-- disenchant started - wait for completion
eventSpam(...)
if (Enchantrix.Settings.GetSetting('chatShowFindings')) then
if arg2 == _ENCH('ArgSpellProspectingName') then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeProspecting"):format(auto_de_prompt.link))
elseif arg2 == _ENCH('ArgSpellname') then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeDisenchanting"):format(auto_de_prompt.link))
elseif arg2 == _ENCH('ArgSpellMillingName') then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeMilling"):format(auto_de_prompt.link))
end
end
hidePrompt()
setState("cast")
end
elseif event == "UNIT_SPELLCAST_INTERRUPTED" then
if arg1 == "player" then
-- interrupted - revert to scanning
eventSpam(...)
hidePrompt()
beginScan()
end
elseif event == "UNIT_SPELLCAST_FAILED" then
if arg1 == "player" then
-- failed - revert to scanning
eventSpam(...)
hidePrompt()
beginScan()
end
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
if isState("cast") and arg1 == "player" and arg2 == auto_de_prompt.Yes:GetAttribute("spell") then
-- completed - wait for loot window to come up
eventSpam(...)
setState("loot_wait")
end
elseif event == "BAG_UPDATE" then
if isState("scan") then
-- bag contents changed - rescan bags
eventSpam(...)
beginScan(arg1)
elseif isState("prompt") and arg1 == auto_de_prompt.bag then
-- verify that our item is still there
local link = GetContainerItemLink(auto_de_prompt.bag, auto_de_prompt.slot)
if link ~= auto_de_prompt.link then
eventSpam(...)
debugSpam(auto_de_prompt.link, "moved/disappeared")
hidePrompt()
local bag, slot, value, spell
link, bag, slot, value, spell = findItemInBags(auto_de_prompt.link)
if link then
-- moved
debugSpam(" found again at [" .. bag .. "," .. slot .. "]")
showPrompt(link, bag, slot, value, spell)
else
-- sold, traded, banked, destroyed, ...
local spellName = auto_de_prompt.Yes:GetAttribute("spell")
if spellName == _ENCH('ArgSpellProspectingName') then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeProspectCancelled"))
elseif spellName == _ENCH('ArgSpellMillingName') then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeMillingCancelled"))
elseif spellName == _ENCH('ArgSpellname') then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeDisenchantCancelled"))
end
hidePrompt()
beginScan()
end
end
end
end
end
local updatedAgo = 0
local function onUpdate(frame, elapsed)
if isState("disabled") then return end
-- only handle initialization and settings changes in here, so don't need to
-- update often. most of the grunt work happens in the event handler
local updateEvery = 1
updatedAgo = updatedAgo + elapsed
if updatedAgo < updateEvery then return end
local enabledInOptions = Enchantrix.Settings.GetSetting('AutoDisenchantEnable')
if enabledInOptions then
if isState("sleep") or isState("init") then
if Enchantrix.Util.GetUserEnchantingSkill() >= 1
or Enchantrix.Util.GetUserJewelCraftingSkill() >= 20
or Enchantrix.Util.GetUserInscriptionSkill() >= 1 then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeActive"))
beginScan()
elseif isState("init") then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeDisabled"))
setState("disabled")
end
end
else
if isState("prompt") or isState("scan") or isState("init") then
Enchantrix.Util.ChatPrint(_ENCH("FrmtAutoDeInactive"))
if isState("prompt") then
clearPrompt()
end
setState("sleep")
end
end
updatedAgo = 0
end
--------------------------------------------------------------------------------
-- Prompt handling
local function getGSC(money)
if (money == nil) then money = 0 end
local g = math.floor(money / 10000)
local s = math.floor((money - (g*10000)) / 100)
local c = math.ceil(money - (g*10000) - (s*100))
return g,s,c
end
local function getTextGSC(money)
if (type(money) ~= "number") then return end
local TEXT_NONE = "0"
local GSC_GOLD="ffd100"
local GSC_SILVER="e6e6e6"
local GSC_COPPER="c8602c"
local GSC_START="|cff%s%d%s|r"
local GSC_PART=".|cff%s%02d%s|r"
local GSC_NONE="|cffa0a0a0"..TEXT_NONE.."|r"
if (not money) then money = 0 end
local g, s, c = getGSC(money)
local gsc = ""
local fmt = GSC_START
if (g > 0) then gsc = gsc..string.format(fmt, GSC_GOLD, g, 'g') fmt = GSC_PART end
if (s > 0) or (c > 0) then gsc = gsc..string.format(fmt, GSC_SILVER, s, 's') fmt = GSC_PART end
if (c > 0) then gsc = gsc..string.format(fmt, GSC_COPPER, c, 'c') end
if (gsc == "") then gsc = GSC_NONE end
return gsc
end
-- declared local at top
function showPrompt(link, bag, slot, value, spell)
clearPrompt() -- safety
-- avoid taint, don't hide or show while in combat
if UnitAffectingCombat("player") then
return
end
debugSpam(link ..",".. bag ..",".. slot ..",".. value ..",".. spell)
local _, count = GetContainerItemInfo(bag, slot)
auto_de_prompt.link, auto_de_prompt.bag, auto_de_prompt.slot, auto_de_prompt.count = link, bag, slot, count
auto_de_prompt.time = GetTime() -- not yet used
local _, _, _, _, _, _, _, _, _, texture = GetItemInfo(auto_de_prompt.link)
auto_de_prompt.Item:SetNormalTexture(texture)
auto_de_prompt.Yes:SetAttribute("target-item", itemStringFromLink(auto_de_prompt.link))
auto_de_prompt.Yes:SetAttribute("spell", spell)
if spell == _ENCH('ArgSpellProspectingName') then
auto_de_prompt.Lines[1]:SetText(_ENCH("GuiAutoProspectPromptLine1"))
auto_de_prompt.Lines[2]:SetText(" " .. auto_de_prompt.link .. "x5")
elseif spell == _ENCH('ArgSpellMillingName') then
auto_de_prompt.Lines[1]:SetText(_ENCH("GuiAutoMillingPromptLine1"))
auto_de_prompt.Lines[2]:SetText(" " .. auto_de_prompt.link .. "x5")
elseif spell == _ENCH('ArgSpellname') then
auto_de_prompt.Lines[1]:SetText(_ENCH("GuiAutoDePromptLine1"))
auto_de_prompt.Lines[2]:SetText(" " .. auto_de_prompt.link)
end
auto_de_prompt.Lines[3]:SetText(_ENCH("GuiAutoDePromptLine3"):format(getTextGSC(floor(value))))
-- clear the lines, just in case
auto_de_prompt.Lines[4]:SetText( nil );
auto_de_prompt.Lines[5]:SetText( nil );
if (BeanCounter and BeanCounter.API) then
local reason = BeanCounter.API.getBidReason(link, count)
if (reason) then
auto_de_prompt.Lines[4]:SetText( format( _ENCH("GuiAutoDEPurchaseReason"), reason ) );
end
end
if (AucAdvanced and AucAdvanced.Modules and AucAdvanced.Modules.Util
and AucAdvanced.Modules.Util.ItemSuggest) then
local suggestion = AucAdvanced.Modules.Util.ItemSuggest.itemsuggest( link, count )
if (suggestion) then
auto_de_prompt.Lines[5]:SetText( format( _ENCH("GuiAutoDESuggestion"), suggestion) );
end
end
auto_de_prompt:Show()
end
-- declared local at top
function hidePrompt()
-- avoid taint, don't hide or show while in combat
if not UnitAffectingCombat("player") then
auto_de_prompt:Hide()
end
end
-- declared local at top
function clearPrompt()
hidePrompt()
auto_de_prompt.link, auto_de_prompt.bag, auto_de_prompt.slot, auto_de_prompt.count, auto_de_prompt.time = nil, nil, nil, nil, nil
-- clear the button target so macro junkies don't get a surprise
auto_de_prompt.Yes:SetAttribute("target-item", nil)
end
local function promptNo()
if auto_de_prompt.link then
ignoreItemSession(auto_de_prompt.link)
end
clearPrompt()
beginScan()
end
local function promptIgnore()
if auto_de_prompt.link then
ignoreItemPermanent(auto_de_prompt.link)
end
clearPrompt()
beginScan()
end
--------------------------------------------------------------------------------
-- Tooltip handling
local function showTooltip()
GameTooltip:SetOwner(auto_de_prompt, "ANCHOR_NONE")
local count = 1
local spellName = auto_de_prompt.Yes:GetAttribute("spell")
if spellName == _ENCH('ArgSpellProspectingName')
or spellName == _ENCH('ArgSpellMillingName') then
count = 5
end
auto_de_tooltip:ShowItemLink(GameTooltip, auto_de_prompt.link, count)
GameTooltip:ClearAllPoints()
GameTooltip:SetPoint("TOPRIGHT", "AutoDisenchantPromptItem", "TOPLEFT", -10, -20)
GameTooltip:Show()
end
local function hideTooltip()
GameTooltip:Hide()
end
--------------------------------------------------------------------------------
-- UI
local function initUI()
-- main frame
auto_de_frame = CreateFrame("Frame")
-- prompt frame
auto_de_prompt = CreateFrame("Frame", "", UIParent)
auto_de_prompt:Hide()
auto_de_prompt:SetPoint("TOP", "UIParent", "TOP", 0, -100)
auto_de_prompt:SetFrameStrata("DIALOG")
auto_de_prompt:SetHeight(170)
auto_de_prompt:SetWidth(400)
auto_de_prompt:SetBackdrop({
bgFile = "Interface/Tooltips/UI-Tooltip-Background",
edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 9, right = 9, top = 9, bottom = 9 }
})
auto_de_prompt:SetBackdropColor(0,0,0, 0.8)
auto_de_prompt:EnableMouse(true)
auto_de_prompt:SetMovable(true)
-- prompt dragbar
auto_de_prompt.Drag = CreateFrame("Button", "", auto_de_prompt)
auto_de_prompt.Drag:SetPoint("TOPLEFT", auto_de_prompt, "TOPLEFT", 10,-5)
auto_de_prompt.Drag:SetPoint("TOPRIGHT", auto_de_prompt, "TOPRIGHT", -10,-5)
auto_de_prompt.Drag:SetHeight(6)
auto_de_prompt.Drag:SetHighlightTexture("Interface\\FriendsFrame\\UI-FriendsFrame-HighlightBar")
auto_de_prompt.Drag:SetScript("OnMouseDown", function() auto_de_prompt:StartMoving() end)
auto_de_prompt.Drag:SetScript("OnMouseUp", function() auto_de_prompt:StopMovingOrSizing() end)
-- prompt item icon
auto_de_prompt.Item = CreateFrame("Button", "AutoDisenchantPromptItem", auto_de_prompt)
auto_de_prompt.Item:SetNormalTexture("Interface\\Buttons\\UI-Slot-Background")
auto_de_prompt.Item:SetPoint("TOPLEFT", auto_de_prompt, "TOPLEFT", 15, -15)
auto_de_prompt.Item:SetHeight(37)
auto_de_prompt.Item:SetWidth(37)
auto_de_prompt.Item:SetScript("OnEnter", showTooltip)
auto_de_prompt.Item:SetScript("OnLeave", hideTooltip)
-- prompt text
auto_de_prompt.Lines = {}
for i = 1, 5 do
auto_de_prompt.Lines[i] = auto_de_prompt:CreateFontString("AutoDisenchantPromptLine"..i, "HIGH")
if (i == 1) then
auto_de_prompt.Lines[i]:SetPoint("TOPLEFT", auto_de_prompt.Item, "TOPRIGHT", 5, 5)
auto_de_prompt.Lines[i]:SetFont("Fonts\\FRIZQT__.TTF",16)
else
auto_de_prompt.Lines[i]:SetPoint("TOPLEFT", auto_de_prompt.Lines[i-1], "BOTTOMLEFT", 0, -5)
auto_de_prompt.Lines[i]:SetFont("Fonts\\FRIZQT__.TTF",13)
end
auto_de_prompt.Lines[i]:SetWidth(350)
auto_de_prompt.Lines[i]:SetJustifyH("LEFT")
auto_de_prompt.Lines[i]:SetText(" ")
end
-- prompt buttons
-- there is no secure version of OptionsButton, so create an invisible
-- OptionsButton (auto_de_prompt.DummyYes) and copy its visual settings across to a
-- SecureActionButton (auto_de_prompt.Yes) to perform the spellcast
local function copyButtonVisuals(dest, source)
dest:ClearAllPoints()
dest:SetPoint("TOPLEFT", source, "TOPLEFT")
dest:SetPoint("BOTTOMRIGHT", source, "BOTTOMRIGHT")
dest:SetNormalTexture(source:GetNormalTexture())
dest:SetHighlightTexture(source:GetHighlightTexture())
dest:SetPushedTexture(source:GetPushedTexture())
dest:SetText(source:GetText())
dest:SetNormalFontObject(GameFontNormal);
dest:SetHighlightFontObject(GameFontHighlight);
end
-- create an invisible "Yes" OptionsButton, then copy its settings
-- across to the secure button
auto_de_prompt.DummyYes = CreateFrame("Button", "", auto_de_prompt, "OptionsButtonTemplate")
auto_de_prompt.DummyYes:SetText(_ENCH("GuiYes"))
auto_de_prompt.DummyYes:SetPoint("BOTTOMRIGHT", auto_de_prompt, "BOTTOMRIGHT", -10, 10)
auto_de_prompt.DummyYes:Hide()
auto_de_prompt.Yes = CreateFrame("Button", "AutoDEPromptYes", auto_de_prompt, "SecureActionButtonTemplate")
copyButtonVisuals(auto_de_prompt.Yes, auto_de_prompt.DummyYes)
auto_de_prompt.Yes:SetAttribute("unit", "none")
auto_de_prompt.Yes:SetAttribute("type", "spell")
auto_de_prompt.No = CreateFrame("Button", "AutoDEPromptNo", auto_de_prompt, "OptionsButtonTemplate")
auto_de_prompt.No:SetText(_ENCH("GuiNo"))
auto_de_prompt.No:SetPoint("BOTTOMRIGHT", auto_de_prompt.Yes, "BOTTOMLEFT", -5, 0)
auto_de_prompt.No:SetScript("OnClick", promptNo)
auto_de_prompt.Ignore = CreateFrame("Button", "AutoDEPromptIgnore", auto_de_prompt, "OptionsButtonTemplate")
auto_de_prompt.Ignore:SetText(_ENCH("GuiIgnore"))
auto_de_prompt.Ignore:SetPoint("BOTTOMRIGHT", auto_de_prompt.No, "BOTTOMLEFT", -5, 0)
auto_de_prompt.Ignore:SetScript("OnClick", promptIgnore)
end
--------------------------------------------------------------------------------
-- Global setup
local function addonLoaded()
if not AutoDisenchantIgnoreList then AutoDisenchantIgnoreList = {} end
setState("init")
initUI()
Stubby.RegisterEventHook("LOOT_OPENED", "Enchantrix.AutoDisenchant", onEvent)
Stubby.RegisterEventHook("LOOT_CLOSED", "Enchantrix.AutoDisenchant", onEvent)
Stubby.RegisterEventHook("UNIT_SPELLCAST_SENT", "Enchantrix.AutoDisenchant", onEvent)
Stubby.RegisterEventHook("UNIT_SPELLCAST_INTERRUPTED", "Enchantrix.AutoDisenchant", onEvent)
Stubby.RegisterEventHook("UNIT_SPELLCAST_FAILED", "Enchantrix.AutoDisenchant", onEvent)
Stubby.RegisterEventHook("UNIT_SPELLCAST_SUCCEEDED", "Enchantrix.AutoDisenchant", onEvent)
Stubby.RegisterEventHook("BAG_UPDATE", "Enchantrix.AutoDisenchant", onEvent)
auto_de_frame:SetScript("OnUpdate", onUpdate)
end
Enchantrix.AutoDisenchant = {
AddonLoaded = addonLoaded,
NameFromIgnoreListItem = nameFromIgnoreListItem,
}