From 6a757cdf51e094a47644e27e23e39805bedb9fdb Mon Sep 17 00:00:00 2001 From: ckaotik Date: Thu, 2 Dec 2010 13:41:00 +0100 Subject: [PATCH] * added AddonLoader support * fixed incorrect auction value calculation * cleaned up the Auctioneer code (hiding API functions is mean!) --- Broker_Garbage.toc | 8 ++- core.lua | 146 +++++++++++++++-------------------------- helper.lua | 182 ++++++++++++++++++++++++++++++++++++---------------- options.lua | 35 ++++++---- 4 files changed, 205 insertions(+), 166 deletions(-) diff --git a/Broker_Garbage.toc b/Broker_Garbage.toc index 0934240..2b43a8e 100644 --- a/Broker_Garbage.toc +++ b/Broker_Garbage.toc @@ -5,10 +5,14 @@ ## SavedVariablesPerCharacter: BG_LocalDB ## Title: Broker_Garbage -## Notes: Full bags no more! Distinguish between junk and treasure, find items to drop quickly. -## Notes-deDE: Endlich wieder Platz! Unterscheide Trödel von Schätzen und finde billigen Müll. ## Author: ckaotik ## Version: 4.0v4 +## Notes: Full bags no more! Distinguish between junk and treasure, find items to drop quickly. +## Notes-deDE: Endlich wieder Platz! Unterscheide Trödel von Schätzen und finde billigen Müll. + +## LoadManagers: AddonLoader +## X-LoadOn-Always: Delayed + ## X-Website: http://www.wowinterface.com/downloads/info15531-Broker_Garbage.html ## X-RelSite-WoWI: 15531 ## X-Category: Inventory diff --git a/core.lua b/core.lua index 7c045ba..6df141e 100644 --- a/core.lua +++ b/core.lua @@ -46,22 +46,22 @@ local cost = 0 -- the amount of money that we repaired for local frame = CreateFrame("frame") local function eventHandler(self, event, arg1, ...) BrokerGarbage:Debug("EVENT", event, arg1, ...) - if event == "PLAYER_ENTERING_WORLD" then - BrokerGarbage:CheckSettings() - - -- some default values initialization - BrokerGarbage.isAtVendor = false - BrokerGarbage.totalBagSpace = 0 - BrokerGarbage.totalFreeSlots = 0 - - -- inventory database - BrokerGarbage.itemsCache = {} - BrokerGarbage.clamInInventory = false - BrokerGarbage.containerInInventory = false - - -- full inventory scan to start with - BrokerGarbage:ScanInventory() - frame:UnregisterEvent("PLAYER_ENTERING_WORLD") + if event == "ADDON_LOADED" and arg1 == "Broker_Garbage" then + BrokerGarbage:CheckSettings() + + -- some default values initialization + BrokerGarbage.isAtVendor = false + BrokerGarbage.totalBagSpace = 0 + BrokerGarbage.totalFreeSlots = 0 + + -- inventory database + BrokerGarbage.itemsCache = {} + BrokerGarbage.clamInInventory = false + BrokerGarbage.containerInInventory = false + + -- full inventory scan to start with + BrokerGarbage:ScanInventory() + frame:UnregisterEvent("ADDON_LOADED") elseif event == "BAG_UPDATE" then if not arg1 or arg1 < 0 or arg1 > 4 then return end @@ -127,7 +127,7 @@ local function eventHandler(self, event, arg1, ...) end -- register events -frame:RegisterEvent("PLAYER_ENTERING_WORLD") +frame:RegisterEvent("ADDON_LOADED") frame:RegisterEvent("BAG_UPDATE") frame:RegisterEvent("MERCHANT_SHOW") frame:RegisterEvent("MERCHANT_CLOSED") @@ -292,7 +292,7 @@ function BrokerGarbage:OnClick(itemTable, button) local LDBclick = false if not itemTable or not itemTable.itemID or type(itemTable.itemID) ~= "number" then BrokerGarbage:Debug("Click on LDB") - itemTable = BrokerGarbage.cheapestItems[1] + itemTable = BrokerGarbage.cheapestItems and BrokerGarbage.cheapestItems[1] LDBclick = true end @@ -345,7 +345,7 @@ function BrokerGarbage:OnClick(itemTable, button) elseif button == "RightButton" then -- open config - InterfaceOptionsFrame_OpenToCategory(BrokerGarbage.options) + InterfaceOptionsFrame_OpenToCategory(BrokerGarbage.options.name) elseif LDBclick then -- click on the LDB to rescan @@ -382,13 +382,13 @@ end -- returns which of the items values is the highest (value, type) function BrokerGarbage:GetSingleItemValue(item) - local hasData = item and GetItemInfo(item) or nil - local itemID = itemLink and BrokerGarbage:GetItemID(itemLink) or nil - - BrokerGarbage:Debug("GetSingleItemValue("..(item or "?")..")", hasData) + if not item then return nil end local hasData, itemLink, itemQuality, itemLevel, _, _, _, _, itemType, _, vendorPrice = GetItemInfo(item) + + BrokerGarbage:Print("GetSingleItemValue("..(item or "?").."), "..(hasData or "no data")) + hasData, itemLink, itemQuality, itemLevel, _, _, _, _, itemType, _, vendorPrice = GetItemInfo(item) if not hasData then -- invalid argument - BrokerGarbage:Debug("Error! GetSingleItemValue: Failed on "..(itemLink or item or "")..".", hasData) + BrokerGarbage:Print("Error! GetSingleItemValue: Failed on "..(itemLink or item or "").."."..(hasData or "no data")) return nil end @@ -397,96 +397,56 @@ function BrokerGarbage:GetSingleItemValue(item) return vendorPrice, vendorPrice and BrokerGarbage.VENDOR end - local auctionPrice, disenchantPrice, source + BrokerGarbage.auctionAddon = nil -- reset this! + local disenchantPrice, auctionPrice, source = 0, 0, nil local canDE = BrokerGarbage:CanDisenchant(itemLink) - BrokerGarbage.auctionAddon = nil - -- calculate auction value + -- calculate auction value: choose the highest auction/disenchant value if IsAddOnLoaded("Auctionator") then BrokerGarbage.auctionAddon = "Auctionator" - auctionPrice = Atr_GetAuctionBuyout(itemLink) + auctionPrice = Atr_GetAuctionBuyout(itemLink) or 0 disenchantPrice = canDE and Atr_GetDisenchantValue(itemLink) - - if auctionPrice and auctionPrice == 0 then - auctionPrice = nil - end - if disenchantPrice and disenchantPrice == 0 then - disenchantPrice = nil - end end + + if IsAddOnLoaded("Auc-Advanced") then -- uses Market Value in any case + BrokerGarbage.auctionAddon = (BrokerGarbage.auctionAddon and BrokerGarbage.auctionAddon..", " or "") .. "Auc-Advanced" + auctionPrice = math.max(auctionPrice, AucAdvanced.API.GetMarketValue(itemLink)) + + if IsAddOnLoaded("Enchantrix") then + disenchantPrice = canDE and math.max(disenchantPrice, select(3, Enchantrix.Storage.GetItemDisenchantTotals(itemLink))) + end + end if IsAddOnLoaded("AuctionLite") then BrokerGarbage.auctionAddon = (BrokerGarbage.auctionAddon and BrokerGarbage.auctionAddon..", " or "") .. "AuctionLite" - auctionPrice = auctionPrice or AuctionLite:GetAuctionValue(itemLink) - disenchantPrice = disenchantPrice or (canDE and AuctionLite:GetDisenchantValue(itemLink)) + auctionPrice = math.max(auctionPrice, AuctionLite:GetAuctionValue(itemLink) or 0) + disenchantPrice = canDE and math.max(disenchantPrice, AuctionLite:GetDisenchantValue(itemLink) or 0) end if IsAddOnLoaded("WOWEcon_PriceMod") then BrokerGarbage.auctionAddon = (BrokerGarbage.auctionAddon and BrokerGarbage.auctionAddon..", " or "") .. "WoWecon" - auctionPrice = auctionPrice or Wowecon.API.GetAuctionPrice_ByLink(itemLink) + auctionPrice = math.max(auctionPrice, Wowecon.API.GetAuctionPrice_ByLink(itemLink) or 0) if canDE and not disenchantPrice then - disenchantPrice = 0 + local tmpPrice = 0 local DEData = Wowecon.API.GetDisenchant_ByLink(itemLink) for i, data in pairs(DEData) do -- [1] = item link, [2] = quantity, [3] = chance - disenchantPrice = disenchantPrice + (Wowecon.API.GetAuctionPrice_ByLink(data[1]) * data[2] * data[3]) + tmpPrice = tmpPrice + (Wowecon.API.GetAuctionPrice_ByLink(data[1]) * data[2] * data[3]) end - disenchantPrice = disenchantPrice ~= 0 and math.floor(disenchantPrice) or nil + disenchantPrice = math.max(disenchantPrice, math.floor(tmpPrice)) end end - if IsAddOnLoaded("Auc-Advanced") then - BrokerGarbage.auctionAddon = (BrokerGarbage.auctionAddon and BrokerGarbage.auctionAddon..", " or "") .. "Auc-Advanced" - auctionPrice = auctionPrice or AucAdvanced.API.GetMarketValue(itemLink) - - if canDE and not disenchantPrice and IsAddOnLoaded("Enchantrix") then - disenchantPrice = 0 - BrokerGarbage:Debug("Item Type?", itemType) - itemType = Enchantrix.Constants.InventoryTypes[itemType] - BrokerGarbage:Debug("Enchantrix Item Type?", itemType) - - local DETable = Enchantrix.Constants.baseDisenchantTable[itemQuality] - BrokerGarbage:Debug("Auc-Advanced: Available data?", itemLink, itemQuality, itemLevel, itemType, - DETable and "EIQ" or "no EIQ", - DETable and DETable[itemType] and "EIQ[type]" or "no EIQ[type]", - DETable and DETable[itemType] and DETable[itemType][itemLevel] and "EIQ[type][level]" or "no EIQ[type][level]") - - if itemQuality and itemLevel and DETable then - while itemLevel < 800 and DETable[itemType] and not DETable[itemType][itemLevel] do - itemLevel = itemLevel + 1 -- we don't know which range is specified in Enchantrix's data - end - BrokerGarbage:Debug(DETable and DETable[itemType] and DETable[itemType][itemLevel] and "EIQ[type][level] found at level "..itemLevel or "no EIQ[type][level] found after 800 cycles!") - - DETable = DETable and DETable[itemType] and DETable[itemType][itemLevel] - if DETable then - local item, chance, amount, itemVal - for i, data in pairs(DETable) do -- [1] = itemID, [2] = drop chance, [3] = quantity - item = data[1] and select(2, GetItemInfo(data[1])) - itemVal = AucAdvanced.API.GetMarketValue(item) or 0 - - disenchantPrice = disenchantPrice + (itemVal * data[2] * data[3]) - end - disenchantPrice = math.floor(disenchantPrice) - else - BrokerGarbage:Debug("Tried to get Enchantrix value of " .. itemLink .. " but failed.") - disenchantPrice = nil - end - else - BrokerGarbage:Debug("Invalid item quality for Enchantrix values of " .. itemLink .. ".") - disenchantPrice = nil - end - end - end - - if not auctionPrice then -- last chance to get auction values - if GetAuctionBuyout then - BrokerGarbage.auctionAddon = BrokerGarbage.auctionAddon or BrokerGarbage.locale.unknown - auctionPrice = GetAuctionBuyout(itemLink) - else - BrokerGarbage.auctionAddon = BrokerGarbage.auctionAddon or BrokerGarbage.locale.na - end - disenchantPrice = (canDE and not disenchantPrice and GetDisenchantValue) and GetDisenchantValue(itemLink) or nil - end + -- last chance to get auction values + if GetAuctionBuyout then + BrokerGarbage.auctionAddon = BrokerGarbage.auctionAddon or BrokerGarbage.locale.unknown + auctionPrice = math.max(auctionPrice, GetAuctionBuyout(itemLink) or 0) + else + BrokerGarbage.auctionAddon = BrokerGarbage.auctionAddon or BrokerGarbage.locale.na + end + if GetDisenchantValue then + disenchantPrice = canDE and math.max(disenchantPrice, GetDisenchantValue(itemLink) or 0) + end -- simply return the highest value price local maximum = math.max((disenchantPrice or 0), (auctionPrice or 0), (vendorPrice or 0)) diff --git a/helper.lua b/helper.lua index 2343dbb..1e68c5a 100644 --- a/helper.lua +++ b/helper.lua @@ -163,6 +163,32 @@ function BrokerGarbage:GetOption(optionName, global) return BG_GlobalDB[optionName] end end +function BrokerGarbage:SetOption(optionName, global, value) + if not global then + BG_LocalDB[optionName] = value + else + BG_GlobalDB[optionName] = value + end +end +function BrokerGarbage:ToggleOption(optionName, global) + if not global then + BG_LocalDB[optionName] = not BG_LocalDB[optionName] + else + BG_GlobalDB[optionName] = not BG_GlobalDB[optionName] + end +end +function BrokerGarbage:RegisterPlugin(name, init) + if not name or not init then + BGC:Print("Error! Cannot register a plugin without a name and initialize function.") + return + end + + table.insert(BrokerGarbage.tabs, { + name = name, + init = init + }) + return #BrokerGarbage.tabs +end -- Helpers -- --------------------------------------------------------- @@ -299,6 +325,37 @@ function BrokerGarbage:ResetAll(global) end end +local interestingPTSets = {"Consumable", "Misc", "Tradeskill"} +BrokerGarbage.PTSets = {} +for set, _ in pairs( BrokerGarbage.PT and BrokerGarbage.PT.sets or {} ) do + local interesting = false + local partials = { strsplit(".", set) } + local maxParts = #partials + + for i = 1, #interestingPTSets do + if strfind(partials[1], interestingPTSets[i]) then + interesting = true + break + end + end + + if interesting then + local pre = BrokerGarbage.PTSets + + for i = 1, maxParts do + if i == maxParts then + -- actual clickable entries + pre[ partials[i] ] = set + else + -- all parts before that + if not pre[ partials[i] ] or type(pre[ partials[i] ]) == "string" then + pre[ partials[i] ] = {} + end + pre = pre[ partials[i] ] + end + end + end +end function BrokerGarbage:LPTDropDown(self, level, functionHandler) local dataTable = BrokerGarbage.PTSets or {} if UIDROPDOWNMENU_MENU_VALUE and string.find(UIDROPDOWNMENU_MENU_VALUE, ".") then @@ -365,76 +422,83 @@ end local scanTooltip = CreateFrame('GameTooltip', 'BGItemScanTooltip', UIParent, 'GameTooltipTemplate') -- misc: either "true" to check only for the current character, or a table {container, slot} for reference -function BrokerGarbage:CanDisenchant(itemLink, misc) - if (itemLink) then +function BrokerGarbage:CanDisenchant(itemLink, location) + if not itemLink then return end + + local required, skillRank = 0 -- required disenchant skill + if IsAddOnLoaded("Enchantrix") then + required = Enchantrix.Util.DisenchantSkillRequiredForItem(itemLink) -- might be more accurate/up to date in case I miss something + skillRank = Enchantrix.Util.GetUserEnchantingSkill() -- Enchantrix caches this. So let's use it! + else + local item = BrokerGarbage:GetCached(BrokerGarbage:GetItemID(itemLink)) + if not item then return end + + quality, level, stackSize = item.quality, item.level, item.stackSize local _, _, quality, level, _, _, _, count, bagSlot = GetItemInfo(itemLink) -- stackables are not DE-able, legendary/heirlooms are not DE-able - if quality and quality >= 2 and quality < 5 and - string.find(bagSlot, "INVTYPE") and not string.find(bagSlot, "BAG") - and (not count or count == 1) then - - -- can this character disenchant? - if IsUsableSpell(BrokerGarbage.enchanting) then - local req = 0 - - if level <= 20 then - req = 1 - elseif level <= 60 then - req = 5*5*math.ceil(level/5)-100 - elseif level <= 99 then - req = 225 - elseif level <= 120 then - req = 275 + if item.quality >= 2 and item.quality < 5 and item.stackSize == 1 + and string.find(item.itemType, "INVTYPE") and not string.find(item.itemType, "BAG") then + + skillRank = BrokerGarbage:GetProfessionSkill(BrokerGarbage.enchanting) or 0 + if skillRank > 0 then + if item.level <= 20 then + required = 1 + elseif item.level <= 60 then + required = 5*5*math.ceil(level/5)-100 + elseif item.level <= 99 then + required = 225 + elseif item.level <= 120 then + required = 275 else - if quality == 2 then -- green - if level <= 150 then - req = 325 - elseif level <= 200 then - req = 350 - elseif level <= 305 then - req = 425 + if item.quality == 2 then -- green + if item.level <= 150 then + required = 325 + elseif item.level <= 200 then + required = 350 + elseif item.level <= 305 then + required = 425 else - req = 475 + required = 475 end - elseif quality == 3 then -- blue - if level <= 200 then - req = 325 - elseif level <= 325 then - req = 450 + elseif item.quality == 3 then -- blue + if item.level <= 200 then + required = 325 + elseif item.level <= 325 then + required = 450 else - req = 500 + required = 500 end - elseif quality == 4 then -- purple - if level <= 199 then - req = 300 - elseif level <= 277 then - req = 375 + elseif item.quality == 4 then -- purple + if item.level <= 199 then + required = 300 + elseif item.level <= 277 then + required = 375 else - req = 500 + required = 500 end end end - - local rank = BrokerGarbage:GetProfessionSkill(BrokerGarbage.enchanting) - if rank and rank >= req then - return true - end - -- if skill rank is too low, still check if we can send it - end - -- misc = "true" => we only care if we ourselves can DE. no twink mail etc. - if misc and type(misc) == "boolean" then return false end - - -- so we can't DE, but can we send it to someone who may? i.e. is the item not soulbound? - if not BG_GlobalDB.hasEnchanter then return false end - if misc and type(misc) == "table" then - return not BrokerGarbage:IsItemSoulbound(itemLink, misc.bag, misc.slot) - else - return not BrokerGarbage:IsItemSoulbound(itemLink) end end end - return false + + if skillRank >= required then + -- this character can disenchant the item. Perfect! + return true + elseif BG_GlobalDB.hasEnchanter then + if location and type(location) == "boolean" then + -- misc = true => Only regard this character. Exit. + return false + elseif location and type(location) == "table" then + -- misc = {bag, slot} => Can we mail this item? + return not BrokerGarbage:IsItemSoulbound(itemLink, location.bag, location.slot) + else + return not BrokerGarbage:IsItemSoulbound(itemLink) + end + else + return false + end end -- returns true if the given item is soulbound @@ -469,7 +533,7 @@ function BrokerGarbage:UpdateCache(itemID) if not itemID then return nil end local class, temp, limit - local hasData, itemLink, quality, _, _, _, subClass, stackSize, invType, _, value = GetItemInfo(itemID) + local hasData, itemLink, quality, itemLevel, _, _, subClass, stackSize, invType, _, value = GetItemInfo(itemID) local family = GetItemFamily(itemID) if not hasData then BrokerGarbage:Debug("UpdateCache("..(itemID or "")..") failed - no GetItemInfo() data available!") @@ -595,6 +659,8 @@ function BrokerGarbage:UpdateCache(itemID) classification = class, quality = quality, family = family, + itemType = itemType, + level = itemLevel, value = value or 0, limit = limit, stackSize = stackSize, @@ -604,8 +670,10 @@ function BrokerGarbage:UpdateCache(itemID) BrokerGarbage.itemsCache[itemID].classification = class BrokerGarbage.itemsCache[itemID].quality = quality BrokerGarbage.itemsCache[itemID].family = family + BrokerGarbage.itemsCache[itemID].itemType = itemType BrokerGarbage.itemsCache[itemID].value = value or 0 BrokerGarbage.itemsCache[itemID].limit = limit + BrokerGarbage.itemsCache[itemID].level = itemLevel BrokerGarbage.itemsCache[itemID].stackSize = stackSize BrokerGarbage.itemsCache[itemID].isClam = BrokerGarbage:Find(BrokerGarbage.clams, itemID) end @@ -613,10 +681,10 @@ end -- fetch an item from the item cache, or insert if it doesn't exist yet function BrokerGarbage:GetCached(itemID) + if not itemID then return end if not BrokerGarbage.itemsCache[itemID] then BrokerGarbage:UpdateCache(itemID) end - return BrokerGarbage.itemsCache[itemID] end diff --git a/options.lua b/options.lua index ca17efe..50e04ed 100644 --- a/options.lua +++ b/options.lua @@ -34,6 +34,11 @@ for set, _ in pairs( BrokerGarbage.PT and BrokerGarbage.PT.sets or {} ) do end end +-- In case the addon is loaded from another condition, always call the remove interface options +if AddonLoader and AddonLoader.RemoveInterfaceOptions then + AddonLoader:RemoveInterfaceOptions("Broker_Garbage") +end + -- options panel / statistics BrokerGarbage.options = CreateFrame("Frame", "BG_Options", InterfaceOptionsFramePanelContainer) BrokerGarbage.options.name = "Broker_Garbage" @@ -677,19 +682,6 @@ local function Options_Statistics(pluginID) end local _ = BrokerGarbage:RegisterPlugin(BrokerGarbage.locale.StatisticsHeading, Options_Statistics) -function BrokerGarbage.CreateOptionsPanel(frame) - local title, subtitle = LibStub("tekKonfig-Heading").new(frame, "Broker_Garbage", BrokerGarbage.locale.BasicOptionsText) - - local group = LibStub("tekKonfig-Group").new(frame, nil, "TOP", subtitle, "BOTTOM", 0, -24) - group:SetPoint("LEFT") - group:SetPoint("BOTTOMRIGHT") - group:SetBackdropColor(0.1, 0.1, 0.1, 0.3) - frame.group = group - - ChangeView(defaultTab) - frame:SetScript("OnShow", UpdateOptionsPanel) -end - -- creates child options frame for setting up one's lists local function ShowListOptions(frame) local title = LibStub("tekKonfig-Heading").new(frame, "Broker_Garbage - " .. BrokerGarbage.locale.LOTitle) @@ -1266,10 +1258,25 @@ local function ShowListOptions(frame) BrokerGarbage.listOptions:SetScript("OnShow", BrokerGarbage.ListOptionsUpdate) end +function BrokerGarbage.CreateOptionsPanel(frame) + local title, subtitle = LibStub("tekKonfig-Heading").new(frame, "Broker_Garbage", BrokerGarbage.locale.BasicOptionsText) + + local group = LibStub("tekKonfig-Group").new(frame, nil, "TOP", subtitle, "BOTTOM", 0, -24) + group:SetPoint("LEFT") + group:SetPoint("BOTTOMRIGHT") + group:SetBackdropColor(0.1, 0.1, 0.1, 0.3) + frame.group = group + + ChangeView(defaultTab) + ShowListOptions(BrokerGarbage.listOptions) + collectgarbage() + frame:SetScript("OnShow", UpdateOptionsPanel) +end + BrokerGarbage.options:SetScript("OnShow", BrokerGarbage.CreateOptionsPanel) InterfaceOptions_AddCategory(BrokerGarbage.options) -BrokerGarbage.listOptions:SetScript("OnShow", ShowListOptions) +-- BrokerGarbage.listOptions:SetScript("OnShow", ShowListOptions) InterfaceOptions_AddCategory(BrokerGarbage.listOptions) LibStub("tekKonfig-AboutPanel").new("Broker_Garbage", "Broker_Garbage") -- 1.7.9.5