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
26 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,
}