You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
858 lines
27 KiB
858 lines
27 KiB
AV = LibStub("AceAddon-3.0"):NewAddon("AutoVendor", "AceConsole-3.0", "AceEvent-3.0")
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("AutoVendor")
|
|
|
|
local options = {
|
|
name = "AutoVendor",
|
|
handler = AV,
|
|
type = 'group',
|
|
args = {
|
|
enable = {
|
|
type = 'toggle',
|
|
order = 1,
|
|
name = L['Autovendor enabled'],
|
|
desc = L['Autovendor enabled description'],
|
|
set = function(info, val) if (val) then AV:Enable() else AV:Disable() end end,
|
|
get = function(info) return AV.enabledState end,
|
|
},
|
|
empty = {
|
|
type = 'header',
|
|
order = 2,
|
|
cmdHidden = true,
|
|
dropdownHidden = true,
|
|
name = L['Sales header'],
|
|
},
|
|
soulbound = {
|
|
type = 'toggle',
|
|
order = 3,
|
|
name = L['Sell unusable'],
|
|
desc = L['Sell unusable description'],
|
|
disabled = function() return not AV.enabledState end,
|
|
set = function(info, val) AV.db.profile.soulbound = val; AV:ResetJunkCache() end,
|
|
get = function(info) return AV.db.profile.soulbound end,
|
|
width = 'full',
|
|
confirm = function(info, val) if val then return L['Sell unusable confirmation'] else return false end end,
|
|
},
|
|
nonoptimal = {
|
|
type = 'toggle',
|
|
order = 4,
|
|
name = L['Sell non-optimal'],
|
|
desc = L['Sell non-optimal description'],
|
|
disabled = function() return not AV.enabledState end,
|
|
set = function(info, val) AV.db.profile.nonoptimal = val; AV:ResetJunkCache() end,
|
|
get = function(info) return AV.db.profile.nonoptimal end,
|
|
width = 'full',
|
|
confirm = function(info, val) if val then return L['Sell non-optimal confirmation'] else return false end end,
|
|
},
|
|
legionArtifactRelics = {
|
|
type = 'toggle',
|
|
order = 4,
|
|
name = L['Sell Legion artifact relics'],
|
|
desc = L['Sell legion artifact relics description'],
|
|
disabled = function() return not AV.enabledState end,
|
|
set = function(info, val) AV.db.profile.selllegionartifact = val; AV:ResetJunkCache() end,
|
|
get = function(info) return AV.db.profile.selllegionartifact end,
|
|
width = 'full'
|
|
},
|
|
fortunecards = {
|
|
type = 'toggle',
|
|
order = 5,
|
|
name = L['Sell cheap fortune cards'],
|
|
desc = L['Sell cheap fortune cards description'],
|
|
disabled = function() return not AV.enabledState end,
|
|
set = function(info, val) AV.db.profile.sellfortunecards = val; AV:ResetJunkCache() end,
|
|
get = function(info) return AV.db.profile.sellfortunecards end,
|
|
width = 'full',
|
|
},
|
|
selllowlevelitems = {
|
|
type = 'toggle',
|
|
order = 6,
|
|
name = L['Sell low level'],
|
|
desc = L['Sell low level description'],
|
|
set = function(info, val) AV.db.profile.selllowlevelitems = val; AV:ResetJunkCache() end,
|
|
get = function(info) return AV.db.profile.selllowlevelitems end,
|
|
disabled = function() return not AV.enabledState end,
|
|
width = 'full',
|
|
confirm = function(info, val) if val then return L['Sell low level confirmation'] else return false end end,
|
|
},
|
|
sellbelowitemlevel = {
|
|
type = 'range',
|
|
order = 7,
|
|
name = L['Sell items below'],
|
|
desc = L['Sell items below description'],
|
|
set = function(info, val) AV.db.profile.sellbelowitemlevel = val; AV:ResetJunkCache() end,
|
|
get = function(info) return AV.db.profile.sellbelowitemlevel end,
|
|
disabled = function() return not AV.enabledState or not AV.db.profile.selllowlevelitems end,
|
|
width = 'full',
|
|
min = 2,
|
|
max = 1000,
|
|
step = 1,
|
|
bigStep = 5,
|
|
},
|
|
verbosity = {
|
|
type = 'select',
|
|
order = 8,
|
|
name = L['Verbosity'],
|
|
desc = L['Verbosity description'],
|
|
disabled = function() return not AV.enabledState end,
|
|
values = {
|
|
none = L['Verbosity none'],
|
|
summary = L['Verbosity summary'],
|
|
all = L['Verbosity all'],
|
|
},
|
|
set = 'SetVerbosity',
|
|
get = 'GetVerbosity',
|
|
},
|
|
empty2 = {
|
|
type = 'header',
|
|
order = 9,
|
|
cmdHidden = true,
|
|
dropdownHidden = true,
|
|
name = L['Auto repair'],
|
|
},
|
|
autorepair = {
|
|
type = 'toggle',
|
|
order = 10,
|
|
name = L['Auto repair'],
|
|
desc = L['Auto repair description'],
|
|
disabled = function() return not AV.enabledState end,
|
|
set = function(info, val) AV.db.profile.autorepair = val end,
|
|
get = function(info) return AV.db.profile.autorepair end,
|
|
width = 'full',
|
|
},
|
|
guildbankrepair = {
|
|
type = 'toggle',
|
|
order = 11,
|
|
name = L['Auto repair guild bank'],
|
|
desc = L['Auto repair guild bank description'],
|
|
disabled = function() return not AV.enabledState or not AV.db.profile.autorepair end,
|
|
set = function(info, val) AV.db.profile.guildbankrepair = val end,
|
|
get = function(info) return AV.db.profile.guildbankrepair end,
|
|
width = 'full',
|
|
},
|
|
junk = {
|
|
type = 'input',
|
|
name = L['Toggle junk'],
|
|
desc = L['Toggle junk description'],
|
|
guiHidden = true,
|
|
dialogHidden = true,
|
|
dropdownHidden = true,
|
|
get = function() return listFormatWithoutPrint(AV.db.profile.junk) end,
|
|
set = function(info, val) AV:ToggleJunk(val, editbox) end,
|
|
},
|
|
notjunk = {
|
|
type = 'input',
|
|
name = L['Toggle NotJunk'],
|
|
desc = L['Toggle NotJunk description'],
|
|
guiHidden = true,
|
|
dialogHidden = true,
|
|
dropdownHidden = true,
|
|
get = function() return listFormatWithoutPrint(AV.db.profile.notjunk) end,
|
|
set = function(info, val) AV:ToggleNotJunk(val, editbox) end,
|
|
},
|
|
debug = {
|
|
type = 'input',
|
|
name = L['Debug'],
|
|
desc = L['Debug description'],
|
|
guiHidden = true,
|
|
dialogHidden = true,
|
|
dropdownHidden = true,
|
|
get = function() return -1 end,
|
|
set = function(info, val) AV:Debug(val, editbox) end,
|
|
}
|
|
},
|
|
}
|
|
|
|
local defaults = {
|
|
profile = {
|
|
verbosity = 'summary',
|
|
autorepair = true,
|
|
guildbankrepair = false,
|
|
soulbound = false,
|
|
sellnonoptimal = false,
|
|
selllegionartifact = false,
|
|
sellfortunecards = false,
|
|
selllowlevelitems = false,
|
|
sellbelowitemlevel = 2,
|
|
not_junk = {
|
|
[1485] = "Pitchfork",
|
|
[39202] = "Rusted Pitchfork",
|
|
[3944] = "Twill Belt",
|
|
[3945] = "Twill Boots",
|
|
[3946] = "Twill Bracers",
|
|
[3947] = "Twill Cloak",
|
|
[8754] = "Twill Cover",
|
|
[3948] = "Twill Gloves",
|
|
[3949] = "Twill Pants",
|
|
[3950] = "Twill Shoulderpads",
|
|
[3951] = "Twill Vest",
|
|
[18230] = "Broken I.W.I.N. Button",
|
|
[33820] = "Weather-Beaten Fishing Hat",
|
|
[38506] = "Don Carlos' Famous Hat",
|
|
[116913] = "Peon's Mining Pick",
|
|
[116916] = "Gorepetal's Gentle Grasp",
|
|
[113547] = "Bouquet of Dried Flowers",
|
|
[168804] = "Powered Piscine Procurement Pole",
|
|
[86125] = "Kafa Press",
|
|
[19969] = "Nat Pagle's Extreme Anglin' Boots",
|
|
[88710] = "Nat's Hat",
|
|
[155459] = "Anglin' Art's Sandals",
|
|
[155484] = "Anglin' Art's Stompers",
|
|
[155476] = "Anglin' Art's Waders",
|
|
[155468] = "Anglin' Art's Treads",
|
|
[19970] = "Arcanite Fishing Pole",
|
|
[19979] = "Hook of the Master Angler",
|
|
[133755] = "Underlight Angler",
|
|
[180136] = "The Brokers Angle\'r"
|
|
},
|
|
junk = {
|
|
},
|
|
}
|
|
}
|
|
|
|
local updateBrokerDisplay = true
|
|
local totalSellValue = 0.0
|
|
local numSlots = 0
|
|
local itemsBOP = {} -- caching items so we don't have to scan tooltips all the time
|
|
local itemsUseEquip = {} -- caching items which have a Use: or Equip: tag so we don't have to scan tooltips all the time
|
|
local itemsJunk = {} -- caching which items are junk
|
|
local cheapestJunkItem = {}
|
|
|
|
function AV:ResetJunkCache()
|
|
itemsJunk = {}
|
|
cheapestJunkItem = {}
|
|
updateBrokerDisplay = true
|
|
end
|
|
|
|
function AV:OnInitialize()
|
|
self.db = LibStub("AceDB-3.0"):New("AutoVendorDB", defaults)
|
|
local parent = LibStub("AceConfig-3.0"):RegisterOptionsTable("AutoVendor", options, {"autovendor", "av"})
|
|
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("AutoVendor", "AutoVendor")
|
|
profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
|
|
LibStub("AceConfig-3.0"):RegisterOptionsTable("AutoVendor.profiles", profiles)
|
|
LibStub("AceConfigDialog-3.0"):AddToBlizOptions("AutoVendor.profiles", "Profiles", "AutoVendor")
|
|
|
|
local UPDATEPERIOD, elapsed = 1, 0
|
|
local ldb = LibStub:GetLibrary("LibDataBroker-1.1", true)
|
|
if ldb then
|
|
local avDataObj = ldb:NewDataObject("AutoVendor", {type = "data source", text = "AutoVendor", icon = "Interface\\Icons\\Inv_Misc_MonsterScales_08"})
|
|
local avF = CreateFrame("frame")
|
|
|
|
avF:SetScript("OnUpdate", function(self, elap)
|
|
elapsed = elapsed + elap
|
|
if elapsed < UPDATEPERIOD then return end
|
|
|
|
elapsed = 0
|
|
local iconSize = select(2, GetChatWindowInfo(1)) - 2
|
|
local repairCost = GetRepairAllCost()
|
|
if repairCost >= 100 then
|
|
repaircost = math.floor(repairCost / 100) * 100
|
|
end
|
|
if updateBrokerDisplay then
|
|
totalSellValue, numSlots = AV:GetJunkAmount()
|
|
if totalSellValue >= 100 then
|
|
totalSellValue = math.floor(totalSellValue / 100) * 100
|
|
end
|
|
updateBrokerDisplay = false
|
|
end
|
|
avDataObj.text = "Repair: "..GetCoinTextureString(repairCost, iconSize).." / Junk: "..GetCoinTextureString(totalSellValue, iconSize).." ("..numSlots.." slots)"
|
|
avDataObj.label = "AutoVendor"
|
|
end)
|
|
end
|
|
end
|
|
|
|
function AV:Debug(val, editbox)
|
|
self:Print('Loaded language: ' .. L["Loaded language"])
|
|
self:Print('Player class: "' .. select(1, UnitClass('player')) .. '"')
|
|
self:Print('Player level: ' .. select(1, UnitLevel('player')))
|
|
|
|
if val:len() < 10 then
|
|
self:Print('Add an item link to the debug statement to get information about that item.')
|
|
return
|
|
end
|
|
|
|
self:Print('Showing information about: ' .. val)
|
|
|
|
local link = GetItemInfo(val)
|
|
local _, _, itemQuality, _, _, _, _, _, itemEquipLoc, _, _, itemClassId, itemSubClassId = GetItemInfo(link)
|
|
local itemLevel = GetDetailedItemLevelInfo(link)
|
|
|
|
if itemQuality then
|
|
self:Print('Item quality: "' .. itemQuality .. '"')
|
|
end
|
|
if itemLevel then
|
|
self:Print('Item level: ' .. itemLevel)
|
|
end
|
|
if itemClassId then
|
|
self:Print('Item Class ID: ' .. itemClassId)
|
|
end
|
|
if itemSubClassId then
|
|
self:Print('Item Subclass ID: ' .. itemSubClassId)
|
|
end
|
|
if itemEquipLoc then
|
|
self:Print('Item equip location: "' .. itemEquipLoc .. '"')
|
|
end
|
|
end
|
|
|
|
function AV:GetJunkAmount()
|
|
local totalSellValue = 0
|
|
local numSlots = 0
|
|
|
|
for bag=0,4 do
|
|
for slot=1,GetContainerNumSlots(bag) do
|
|
local link = GetContainerItemLink(bag, slot)
|
|
if link and AV:IsJunk(link) then
|
|
local itemCount = select(2, GetContainerItemInfo(bag, slot))
|
|
if itemCount then
|
|
local vendorWorth = select(11, GetItemInfo(link))
|
|
if vendorWorth then
|
|
local sellValue = itemCount * vendorWorth
|
|
if sellValue > 0 then
|
|
numSlots = numSlots + 1
|
|
totalSellValue = totalSellValue + sellValue
|
|
end
|
|
|
|
if cheapestJunkItem["link"] == nil or cheapestJunkItem["price"] > sellValue then
|
|
cheapestJunkItem["link"] = link
|
|
cheapestJunkItem["price"] = sellValue
|
|
cheapestJunkItem["bag"] = bag
|
|
cheapestJunkItem["slot"] = slot
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return totalSellValue, numSlots
|
|
end
|
|
|
|
function AV:OnEnable()
|
|
self:RegisterEvent("BAG_UPDATE")
|
|
self:RegisterEvent("MERCHANT_SHOW")
|
|
self:RegisterChatCommand("junklist", "JunkList")
|
|
self:RegisterChatCommand("notjunklist", "NotJunkList")
|
|
self:RegisterChatCommand("junk", "ToggleJunk")
|
|
self:RegisterChatCommand("notjunk", "ToggleNotJunk")
|
|
self:RegisterChatCommand("dropcheapest", "DropCheapest")
|
|
end
|
|
|
|
function AV:OnDisable()
|
|
end
|
|
|
|
function AV:SetVerbosity(info, val)
|
|
self.db.profile.verbosity = val
|
|
self:Print("Setting verbosity level to '"..val.."'.")
|
|
end
|
|
|
|
function AV:GetVerbosity(info)
|
|
return self.db.profile.verbosity
|
|
end
|
|
|
|
local function listFormatWithoutPrint(list)
|
|
local tmpList = {}
|
|
for _,v in pairs(list) do
|
|
table.insert(tmpList, v)
|
|
end
|
|
table.sort(tmpList)
|
|
tmpString = ''
|
|
for k,v in pairs(list) do
|
|
local item_link = select(2, GetItemInfo(k))
|
|
if item_link == nil then
|
|
item_link = v
|
|
end
|
|
if #tmpString > 0 and #tmpString + #item_link <= 255 then
|
|
tmpString = tmpString .. ', ' .. item_link
|
|
else
|
|
if #tmpString == 0 then
|
|
tmpString = item_link
|
|
else
|
|
AV:Print(tmpString)
|
|
tmpString = item_link
|
|
end
|
|
end
|
|
end
|
|
return tmpString
|
|
end
|
|
|
|
local function listFormat(list)
|
|
tmpString = listFormatWithoutPrint(list)
|
|
if #tmpString ~= 0 then
|
|
AV:Print(tmpString)
|
|
end
|
|
end
|
|
|
|
local function listRemove(list, item)
|
|
found = false
|
|
for k,v in pairs(list) do
|
|
if string.lower(v) == string.lower(item) then
|
|
list[k] = nil
|
|
found = true
|
|
end
|
|
end
|
|
return found
|
|
end
|
|
|
|
local function listToggle(list, listName, itemId, itemName)
|
|
if list[itemId] then
|
|
list[itemId] = nil
|
|
AV:Print(string.format(L['Removed from list'], itemName, listName))
|
|
else
|
|
table.insert(list, itemId, itemName)
|
|
AV:Print(string.format(L['Added to list'], itemName, listName))
|
|
end
|
|
end
|
|
|
|
function AV:ToggleJunk(msg, editbox)
|
|
if msg then
|
|
self:ResetJunkCache()
|
|
local itemId = tonumber(strmatch(msg, "item:(%d+)"))
|
|
local itemName = select(1, GetItemInfo(msg))
|
|
if itemId and itemName then
|
|
listToggle(self.db.profile.junk, 'junk list', itemId, itemName)
|
|
else
|
|
if msg and listRemove(self.db.profile.junk, msg) then
|
|
self:Print(string.format(L['Removed from list'], msg, 'junk list'))
|
|
else
|
|
self:Print(L['No item link'])
|
|
end
|
|
end
|
|
else
|
|
self:Print(L['No item link'])
|
|
end
|
|
end
|
|
|
|
function AV:ToggleNotJunk(msg, editbox)
|
|
if msg then
|
|
self:ResetJunkCache()
|
|
local itemId = tonumber(strmatch(msg, "item:(%d+)"))
|
|
local itemName = select(1, GetItemInfo(msg))
|
|
if itemId and itemName then
|
|
listToggle(self.db.profile.not_junk, 'not junk list', itemId, itemName)
|
|
else
|
|
if msg and listRemove(self.db.profile.not_junk, msg) then
|
|
self:Print(string.format(L['Removed from list'], msg, 'not junk list.'))
|
|
else
|
|
self:Print(L['No item link'])
|
|
end
|
|
end
|
|
else
|
|
self:Print(L['No item link'])
|
|
end
|
|
end
|
|
|
|
function AV:JunkList(msg, editbox)
|
|
local empty = true
|
|
for _,_ in pairs(self.db.profile.junk) do
|
|
empty = false
|
|
end
|
|
if empty then
|
|
self:Print(L['Junk list empty'])
|
|
else
|
|
self:Print(L['Items in junk list'])
|
|
end
|
|
listFormat(self.db.profile.junk)
|
|
end
|
|
|
|
function AV:NotJunkList(msg, editbox)
|
|
local empty = true
|
|
for _,_ in pairs(self.db.profile.not_junk) do
|
|
empty = false
|
|
end
|
|
if empty then
|
|
self:Print(L['Not-junk list empty'])
|
|
else
|
|
self:Print(L['Items in not-junk list'])
|
|
end
|
|
listFormat(self.db.profile.not_junk)
|
|
end
|
|
|
|
function AV:DropCheapest(msg, editbox)
|
|
if cheapestJunkItem["link"] ~= nil then
|
|
self:Print(string.format(L['Throwing away'], cheapestJunkItem["link"]))
|
|
if not CursorHasItem() then
|
|
PickupContainerItem(cheapestJunkItem["bag"], cheapestJunkItem["slot"])
|
|
DeleteCursorItem()
|
|
end
|
|
else
|
|
self:Print(L['No junk to throw away'])
|
|
end
|
|
end
|
|
|
|
function AV:IsJunk(link)
|
|
local itemId = tonumber(strmatch(link, "item:(%d+)"))
|
|
|
|
if itemId == nil then
|
|
return false
|
|
else
|
|
if itemsJunk[itemId] == nil then
|
|
itemsJunk[itemId] = self:ShouldSell(link)
|
|
end
|
|
|
|
return itemsJunk[itemId]
|
|
end
|
|
end
|
|
|
|
function AV:ShouldSell(link)
|
|
local itemId = tonumber(strmatch(link, "item:(%d+)"))
|
|
local itemName, _, itemQuality, _, _, _, _, _, itemEquipLoc, _, _, itemClassId, itemSubClassId = GetItemInfo(link)
|
|
local itemLevel = GetDetailedItemLevelInfo(link)
|
|
|
|
-- Noboru's Cudgel
|
|
if itemId == 6196 then
|
|
return false
|
|
end
|
|
|
|
-- Peon's Mining Pick
|
|
if itemId == 116913 then
|
|
return false
|
|
end
|
|
|
|
-- Don't sell legendary, artifact or heirloom items
|
|
if itemQuality and itemQuality > 4 then
|
|
return false
|
|
end
|
|
|
|
-- item is in the "always sell" list
|
|
if self.db.profile.junk[itemId] then
|
|
return true
|
|
end
|
|
|
|
-- item is in the "never sell" list
|
|
if self.db.profile.not_junk[itemId] then
|
|
return false
|
|
end
|
|
|
|
if self.db.profile.sellfortunecards and AV_FORTUNE_CARDS[itemId] == true then
|
|
return true
|
|
end
|
|
|
|
if self.db.profile.selllegionartifact and itemClassId == LE_ITEM_CLASS_GEM and itemSubClassId == LE_ITEM_GEM_ARTIFACTRELIC then
|
|
return true
|
|
end
|
|
|
|
-- item is level 1, don't sell
|
|
if itemLevel == 1 and itemQuality ~= 0 then
|
|
return false
|
|
end
|
|
|
|
if itemsBOP[itemId] == nil or itemsUseEquip[itemId] == nil then
|
|
local soulbound, useEquip = self:GetTooltipInfo(link)
|
|
itemsBOP[itemId] = soulbound
|
|
itemsUseEquip[itemId] = useEquip
|
|
end
|
|
|
|
local _,class = UnitClass('player')
|
|
|
|
if itemClassId == LE_ITEM_CLASS_WEAPON or itemClassId == LE_ITEM_CLASS_ARMOR then
|
|
-- sell items below a certain item level
|
|
if itemsBOP[itemId] and not itemsUseEquip[itemId] and AV.db.profile.selllowlevelitems and itemLevel < AV.db.profile.sellbelowitemlevel then
|
|
return true
|
|
end
|
|
|
|
-- sell unusable soulbound items
|
|
if self.db.profile.soulbound then
|
|
-- sell unusable items
|
|
if itemsBOP[itemId] and AV:CannotUse(class, itemClassId, itemSubClassId) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
-- sell non-optimal soulbound items
|
|
if self.db.profile.nonoptimal then
|
|
local _,class = UnitClass('player')
|
|
|
|
if itemClassId == LE_ITEM_CLASS_ARMOR and itemEquipLoc ~= 'INVTYPE_CLOAK' and itemsBOP[itemId] then
|
|
if AV:NonOptimal(class, itemClassId, itemSubClassId) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
-- item is grey
|
|
if itemQuality == 0 then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function AV:GetTooltipInfo(link)
|
|
local soulbound = false
|
|
local useEquip = false
|
|
|
|
local f = CreateFrame('GameTooltip', 'AVTooltip', UIParent, 'GameTooltipTemplate')
|
|
f:SetOwner(UIParent, 'ANCHOR_NONE')
|
|
f:SetHyperlink(link)
|
|
|
|
for i = 0,20 do
|
|
local tooltipLine = _G['AVTooltipTextLeft' .. i]
|
|
if tooltipLine ~= nil then
|
|
local tooltipString = tooltipLine:GetText()
|
|
|
|
if self:FindString(tooltipString, ITEM_BIND_ON_PICKUP) then
|
|
soulbound = true
|
|
end
|
|
|
|
if self:FindString(tooltipString, USE_COLON) or self:FindString(tooltipString, L['Equip:']) then
|
|
useEquip = true
|
|
end
|
|
end
|
|
end
|
|
|
|
f:Hide()
|
|
|
|
return soulbound, useEquip
|
|
end
|
|
|
|
function AV:FindString(haystack, needle)
|
|
if haystack == nil then
|
|
return false
|
|
end
|
|
|
|
return string.find(haystack, needle)
|
|
end
|
|
|
|
function AV:MERCHANT_SHOW()
|
|
local iconSize = select(2, GetChatWindowInfo(1)) - 2
|
|
local totalSellValue = 0
|
|
local totalItemsSold = 0
|
|
local repairCost = 0
|
|
local usedGuildBankRepair = false
|
|
local warningShown = false
|
|
|
|
if self.db.profile.autorepair and CanMerchantRepair() then
|
|
repairCost, canRepair = GetRepairAllCost()
|
|
if canRepair then
|
|
if self.db.profile.guildbankrepair and CanGuildBankRepair() and GetGuildBankWithdrawMoney() >= repairCost then
|
|
usedGuildBankRepair = true
|
|
RepairAllItems(true)
|
|
else
|
|
RepairAllItems()
|
|
end
|
|
end
|
|
end
|
|
|
|
for bag=0,4 do
|
|
for slot=1,GetContainerNumSlots(bag) do
|
|
local link = GetContainerItemLink(bag, slot)
|
|
if link then
|
|
local itemId = tonumber(strmatch(link, "item:(%d+)"))
|
|
if AV:IsJunk(link) then
|
|
if totalItemsSold == 12 then
|
|
if not warningShown then
|
|
self:Print(L['12 items sold'])
|
|
warningShown = true
|
|
end
|
|
else
|
|
local itemCount = select(2, GetContainerItemInfo(bag, slot))
|
|
local sellValue = itemCount * select(11, GetItemInfo(link))
|
|
if sellValue > 0 then
|
|
totalSellValue = totalSellValue + sellValue
|
|
totalItemsSold = totalItemsSold + 1
|
|
UseContainerItem(bag, slot)
|
|
if self.db.profile.verbosity == 'all' then
|
|
self:Print(format(L['Selling x of y for z'], link, itemCount, GetCoinTextureString(sellValue, iconSize)))
|
|
end
|
|
else
|
|
if self.db.profile.verbosity == 'all' then
|
|
self:Print(format(L['Item has no vendor worth'], link))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.db.profile.verbosity == 'all' or self.db.profile.verbosity == 'summary' then
|
|
if totalItemsSold > 0 then
|
|
local items = L['Multiple items']
|
|
if totalItemsSold == 1 then
|
|
items = L['Single item']
|
|
end
|
|
self:Print(format(L['Summary sold x item(s) for z'], totalItemsSold, items, GetCoinTextureString(totalSellValue, iconSize)))
|
|
end
|
|
if repairCost > 0 then
|
|
if usedGuildBankRepair then
|
|
self:Print(format(L['Repaired all items for x from guild bank'], GetCoinTextureString(repairCost, iconSize)))
|
|
else
|
|
self:Print(format(L['Repaired all items for x'], GetCoinTextureString(repairCost, iconSize)))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function AV:BAG_UPDATE()
|
|
cheapestJunkItem = {}
|
|
updateBrokerDisplay = true
|
|
end
|
|
|
|
function AV:CannotUse(class, itemClassId, itemSubClassId)
|
|
for _,v in pairs(AV_UNUSABLE_ITEMS[class][itemClassId]) do
|
|
if itemSubClassId == v then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function AV:NonOptimal(class, itemClassId, itemSubClassId)
|
|
for _,v in pairs(AV_NON_OPTIMAL_ITEMS[class][itemClassId]) do
|
|
if itemSubClassId == v then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Format: AV_UNUSABLE_ITEMS[class][itemClassId][itemSubClassId]
|
|
AV_UNUSABLE_ITEMS = {
|
|
['DEATHKNIGHT'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_STAFF, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_DAGGER, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['DEMONHUNTER'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_STAFF, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_MACE1H },
|
|
},
|
|
['DRUID'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_SWORD1H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['HUNTER'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_MACE1H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['MAGE'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE1H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['MONK'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_DAGGER, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['PALADIN'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_STAFF, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_DAGGER, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['PRIEST'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD1H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['ROGUE'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_STAFF, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['SHAMAN'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_PLATE },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD1H, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['WARLOCK'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL, LE_ITEM_ARMOR_PLATE, LE_ITEM_ARMOR_SHIELD },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_AXE1H, LE_ITEM_WEAPON_AXE2H, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_MACE1H, LE_ITEM_WEAPON_MACE2H, LE_ITEM_WEAPON_POLEARM, LE_ITEM_WEAPON_SWORD2H, LE_ITEM_WEAPON_UNARMED, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
['WARRIOR'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { },
|
|
[LE_ITEM_CLASS_WEAPON] = { LE_ITEM_WEAPON_WAND, LE_ITEM_WEAPON_BOWS, LE_ITEM_WEAPON_GUNS, LE_ITEM_WEAPON_CROSSBOW, LE_ITEM_WEAPON_THROWN, LE_ITEM_WEAPON_WARGLAIVE },
|
|
},
|
|
}
|
|
|
|
-- Format: AV_NON_OPTIMAL_ITEMS[class][itemClassId][itemSubClassId]
|
|
AV_NON_OPTIMAL_ITEMS = {
|
|
['DEATHKNIGHT'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH, LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL },
|
|
},
|
|
['DEMONHUNTER'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH },
|
|
},
|
|
['DRUID'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH },
|
|
},
|
|
['HUNTER'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH, LE_ITEM_ARMOR_LEATHER },
|
|
},
|
|
['MAGE'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { },
|
|
},
|
|
['MONK'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH },
|
|
},
|
|
['PALADIN'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH, LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL },
|
|
},
|
|
['PRIEST'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { },
|
|
},
|
|
['ROGUE'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH },
|
|
},
|
|
['SHAMAN'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH, LE_ITEM_ARMOR_LEATHER },
|
|
},
|
|
['WARLOCK'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { },
|
|
},
|
|
['WARRIOR'] = {
|
|
[LE_ITEM_CLASS_ARMOR] = { LE_ITEM_ARMOR_CLOTH, LE_ITEM_ARMOR_LEATHER, LE_ITEM_ARMOR_MAIL },
|
|
},
|
|
}
|
|
|
|
AV_FORTUNE_CARDS = {
|
|
[62590] = true,
|
|
[60845] = true,
|
|
[62606] = true,
|
|
[60842] = true,
|
|
[60841] = true,
|
|
[62602] = true,
|
|
[62603] = true,
|
|
[62604] = true,
|
|
[62605] = true,
|
|
[60839] = true,
|
|
[62598] = true,
|
|
[62599] = true,
|
|
[62600] = true,
|
|
[62601] = true,
|
|
[62246] = true,
|
|
[62577] = true,
|
|
[62578] = true,
|
|
[62579] = true,
|
|
[62580] = true,
|
|
[62581] = true,
|
|
[62582] = true,
|
|
[62583] = true,
|
|
[62584] = true,
|
|
[62585] = true,
|
|
[62586] = true,
|
|
[62587] = true,
|
|
[62588] = true,
|
|
[62589] = true,
|
|
[60843] = true,
|
|
[62591] = true,
|
|
[62247] = true,
|
|
[62552] = true,
|
|
[62553] = true,
|
|
[62554] = true,
|
|
[62555] = true,
|
|
[62556] = true,
|
|
[62557] = true,
|
|
[62558] = true,
|
|
[62559] = true,
|
|
[62560] = true,
|
|
[62561] = true,
|
|
[62562] = true,
|
|
[62563] = true,
|
|
[62564] = true,
|
|
[62565] = true,
|
|
[62566] = true,
|
|
[62567] = true,
|
|
[62568] = true,
|
|
[62569] = true,
|
|
[62570] = true,
|
|
[62571] = true,
|
|
[62572] = true,
|
|
[62573] = true,
|
|
[62574] = true,
|
|
[62575] = true,
|
|
[62576] = true,
|
|
}
|
|
|