722 lines
24 KiB
Lua
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,
|
|
|
|
}
|