From 5c3dc13aabc84bb8b4b8d6d5886331e3986f61c0 Mon Sep 17 00:00:00 2001 From: ckaotik Date: Fri, 12 Mar 2010 00:37:42 +0100 Subject: [PATCH] CRITICAL! I get another feature. Added Loot Manager and fixed a whole bunch of bugs. Feedback welcome. --- Broker_Garbage.toc | 13 +- core.lua | 400 +++++++++++++++++++++++++++------------ deDE.lua | 54 +++++- enUS.lua | 54 +++++- lootmanager.lua | 484 +++++++++++++++++++++++++++++++++++++++++++++++ lootmanager_options.lua | 196 +++++++++++++++++++ options.lua | 141 ++++++++++++-- readme.txt | 24 ++- 8 files changed, 1211 insertions(+), 155 deletions(-) create mode 100644 lootmanager.lua create mode 100644 lootmanager_options.lua diff --git a/Broker_Garbage.toc b/Broker_Garbage.toc index a73ef09..1cb3597 100644 --- a/Broker_Garbage.toc +++ b/Broker_Garbage.toc @@ -8,11 +8,12 @@ ## Notes: Full bags no more! Find your least valuable item .. and destroy it! ## Notes-deDE: Endlich wieder Platz! Finde dein billigstes Item ... und zerstöre es. ## Author: ckaotik -## Version: 3.3v16 +## Version: 3.3v17beta1 ## X-Embeds: LibPeriodicTable-3.1 ## X-Category: Inventory -## X-Credits: GarbageFu, Tekkub +## X-Credits: GarbageFu(Jaerin/wmrojer), tekKonfig(Tekkub), KarniCrap(Karnifex) +# dependencies. comment (with '#') if you do not wish to load these (only if another addon already does so) Libs\LibStub.lua Libs\LibQTip-1.0.lua Libs\CallbackHandler-1.0.lua @@ -24,8 +25,14 @@ Libs\LibPeriodicTable-3.1-Misc\LibPeriodicTable-3.1-Misc.lua Libs\LibPeriodicTable-3.1-Tradeskill\LibPeriodicTable-3.1-Tradeskill.lua Libs\LibPeriodicTable-3.1-TradeskillResultMats\LibPeriodicTable-3.1-TradeskillResultMats.lua +# localization files enUS.lua deDE.lua +# loot manager functionality can be disabled here. comment (with '#') lootmanager.lua to disable core.lua -options.lua \ No newline at end of file +lootmanager.lua + +# options. when disabling the Loot Manager, disable lootmanager_options.lua, too +options.lua +lootmanager_options.lua \ No newline at end of file diff --git a/core.lua b/core.lua index 9434486..abea259 100644 --- a/core.lua +++ b/core.lua @@ -32,6 +32,17 @@ BrokerGarbage.defaultGlobalSettings = { autoSellToVendor = true, autoRepairAtVendor = true, neverRepairGuildBank = false, + useLootManager = false, + restackIfNeeded = true, + restackFullInventory = false, + autoLoot = false, + autoLootSkinning = true, + autoLootFishing = true, + autoLootPickpocket = true, + autoDestroy = false, + tooFewSlots = 0, + openContainers = true, + openClams = true, -- default values tooltipMaxHeight = 220, @@ -63,6 +74,7 @@ BrokerGarbage.defaultLocalSettings = { -- behavior neverRepairGuildBank = false, + selectiveLooting = false, -- default values moneyLostByDeleting = 0, @@ -78,6 +90,15 @@ local cost = 0 local lastReminder = time() BrokerGarbage.tt = nil +BrokerGarbage.warnings = {} +BrokerGarbage.tagAuction = "|cFF2bff58A" -- green +BrokerGarbage.tagVendor = "|cFFff9c5aV" -- orange +BrokerGarbage.tagVendorList = "|cFFff592dV" -- slightly darker orange +BrokerGarbage.tagDisenchant = "|cFFe052ffD" -- purple +BrokerGarbage.tagInclude = "|cFFFFFFFFI" -- white + +BrokerGarbage.clams = {15874, 5523, 5524, 7973, 24476, 36781, 45909} +BrokerGarbage.playerClass = select(2,UnitClass("player")) -- event handler local function eventHandler(self, event, ...) @@ -111,7 +132,7 @@ local function eventHandler(self, event, ...) elseif sellValue ~= 0 and BG_GlobalDB.autoSellToVendor then -- autosell only BrokerGarbage:Print(format(BrokerGarbage.locale.sell, BrokerGarbage:FormatMoney(sellValue))) - + end sellValue = 0 @@ -124,10 +145,10 @@ local function eventHandler(self, event, ...) elseif locked and event == "MERCHANT_CLOSED" then -- fallback unlock - sellValue = 0 cost = 0 - locked = false + sellValue = 0 BrokerGarbage.toSellValue = 0 + locked = false BrokerGarbage:Debug("lock released") BrokerGarbage:ScanInventory() @@ -136,14 +157,14 @@ local function eventHandler(self, event, ...) BrokerGarbage:CheckSettings() if not locked and loaded then - warnings = BrokerGarbage:ScanInventory() + BrokerGarbage:ScanInventory() end - + elseif event == "BAG_UPDATE" then if not locked and loaded then BrokerGarbage:ScanInventory() end - + end end @@ -244,19 +265,44 @@ end function BrokerGarbage:CheckSettings() -- check for settings - if not BG_GlobalDB then BG_GlobalDB = {} end + local first = false + if not BG_GlobalDB then BG_GlobalDB = {}; first = true end for key, value in pairs(BrokerGarbage.defaultGlobalSettings) do if BG_GlobalDB[key] == nil then BG_GlobalDB[key] = value end end - if not BG_LocalDB then BG_LocalDB = {} end + if not BG_LocalDB then BG_LocalDB = {}; first = true end for key, value in pairs(BrokerGarbage.defaultLocalSettings) do if BG_LocalDB[key] == nil then BG_LocalDB[key] = value end end + + if first then + BrokerGarbage:CreateDefaultLists() + end +end + +function BrokerGarbage:CreateDefaultLists() + BG_GlobalDB.include[46106] = true -- argentum lance + BG_GlobalDB.include[6265] = 20 -- soulshards + BG_GlobalDB.include["Consumable.Water.Conjured"] = true + + BG_LocalDB.exclude["Tradeskill.Mat"] = true + if BrokerGarbage.playerClass == "HUNTER" then + BG_LocalDB.exclude["Misc.Reagent.Ammo"] = true + elseif BrokerGarbage.playerClass == "WARRIOR" or BrokerGarbage.playerClass == "ROGUE" or BrokerGarbage.playerClass == "DEATHKNIGHT" then + BG_LocalDB.autoSellList["Consumable.Water"] = true + elseif BrokerGarbage.playerClass == "SHAMAN" then + BG_LocalDB.include[17058] = 20 -- fish oil + BG_LocalDB.include[17057] = 20 -- scales + end + BG_LocalDB.exclude["Misc.Reagent.Class."..string.gsub(string.lower(BrokerGarbage.playerClass), "^.", string.upper)] = true + + BG_GlobalDB.forceVendorPrice["Consumable.Food.Edible"] = true + BG_GlobalDB.forceVendorPrice["Consumable.Water.Basic"] = true end function BrokerGarbage:FormatMoney(amount) @@ -323,6 +369,21 @@ function BrokerGarbage:Find(table, value) return false end +function BrokerGarbage:IsItem(itemID, itemTable) + if type(itemTable) == "number" then + return itemID == itemTable + + else + for _, ID in pairs(itemTable) do + if itemID == ID then + return true + end + end + end + + return false +end + -- joins any number of tables together, one after the other. elements within the input-tables will get mixed, though function BrokerGarbage:JoinTables(...) local result = {} @@ -390,6 +451,16 @@ function BrokerGarbage:GetItemID(itemLink) return tonumber(itemID) end +function BrokerGarbage:GetTradeSkill(skillName) + for i=1, GetNumSkillLines() do + local name, _, _, skillRank, _, _, _, _, _, _, _, _, _ = GetSkillLineInfo(i) + if name == skillName then + return skillRank + end + end + return nil +end + function BrokerGarbage:CanDisenchant(itemLink) if (itemLink) then local _, _, quality, level, _, _, _, count, slot = GetItemInfo(itemLink) @@ -400,17 +471,9 @@ function BrokerGarbage:CanDisenchant(itemLink) and (not count or count == 1) then -- can we DE ourself? - local enchanting = GetSpellInfo(7411) + local enchanting = select(1,GetSpellInfo(7411)) if IsUsableSpell(enchanting) then - local skill - for i=1, GetNumSkillLines() do - local name, _, _, skillRank, _, _, _, _, _, _, _, _, _ = GetSkillLineInfo(i) - if name == enchanting then - skill = skillRank - BrokerGarbage:Debug("DE Skill", skill) - break - end - end + local skill = BrokerGarbage:GetTradeSkill(enchanting) or 0 local requiredSkill = 0 if level <= 20 then @@ -428,10 +491,8 @@ function BrokerGarbage:CanDisenchant(itemLink) else requiredSkill = 375 end - BrokerGarbage:Debug("Required DE Skill", requiredSkill) if skill >= requiredSkill then - BrokerGarbage:Debug("Can Diss.") return true end -- if skill is too low, still check if we can send it @@ -475,7 +536,7 @@ function BrokerGarbage:Tooltip(wut) -- shows up to n lines of deletable items local lineNum local cheapList = BrokerGarbage:GetCheapest(BG_GlobalDB.tooltipNumItems) - for i = 1, #cheapList do + for i = 1, #cheapList do -- adds lines: itemLink, count, itemPrice, source lineNum = BrokerGarbage.tt:AddLine( select(2,GetItemInfo(cheapList[i].itemID)), @@ -575,10 +636,10 @@ end -- calculates the value of a stack/partial stack of an item function BrokerGarbage:GetItemValue(itemLink, count) - local vendorPrice = select(11,GetItemInfo(itemLink)) local itemID = BrokerGarbage:GetItemID(itemLink) - local auctionPrice, disenchantPrice, temp, source - local DE = false + local DE = BrokerGarbage:CanDisenchant(itemLink) + local vendorPrice = select(11,GetItemInfo(itemLink)) + local auctionPrice, disenchantPrice, source if vendorPrice == 0 then vendorPrice = nil end if not count then count = GetItemCount(itemLink, false, false) end @@ -600,17 +661,17 @@ function BrokerGarbage:GetItemValue(itemLink, count) end end if select(3,GetItemInfo(itemLink)) == 0 or useVendorPrice then - return vendorPrice and vendorPrice*count or nil, "|cFFF5DEB3V" -- orange + return vendorPrice and vendorPrice*count or nil, BrokerGarbage.tagVendor end -- calculate auction value if IsAddOnLoaded("Auctionator") then auctionPrice = Atr_GetAuctionBuyout(itemLink) - disenchantPrice = Atr_GetDisenchantValue(itemLink) + disenchantPrice = DE and Atr_GetDisenchantValue(itemLink) elseif IsAddOnLoaded("AuctionLite") then auctionPrice = AuctionLite:GetAuctionValue(itemLink) - disenchantPrice = AuctionLite:GetDisenchantValue(itemLink) + disenchantPrice = DE and AuctionLite:GetDisenchantValue(itemLink) elseif IsAddOnLoaded("WOWEcon_PriceMod") then auctionPrice = Wowecon.API.GetAuctionPrice_ByLink(itemLink, Wowecon.API.SERVER_PRICE) @@ -620,6 +681,7 @@ function BrokerGarbage:GetItemValue(itemLink, count) for i,data in pairs(DeData) do disenchantPrice = disenchantPrice + (Wowecon.API.GetAuctionPrice_ByLink(data[1], Wowecon.API.SERVER_PRICE) * data[3]) end + disenchantPrice = DE and disenchantPrice elseif IsAddOnLoaded("Auc-Advanced") then auctionPrice = AucAdvanced.API.GetMarketValue(itemLink) @@ -627,52 +689,79 @@ function BrokerGarbage:GetItemValue(itemLink, count) else auctionPrice = GetAuctionBuyout and GetAuctionBuyout(itemLink) or nil - disenchantPrice = GetDisenchantValue and GetDisenchantValue(itemLink) or nil - - -- no auctionPrice => no auction addon loaded + disenchantPrice = DE and GetDisenchantValue and GetDisenchantValue(itemLink) or nil + end - -- DE items might be worth more than auction selling - if BrokerGarbage:CanDisenchant(itemLink) then - DE = true - --auctionPrice = (disenchantPrice > auctionPrice) and disenchantPrice or auctionPrice + local maximum = math.max((disenchantPrice or 0), (auctionPrice or 0), (vendorPrice or 0)) + if vendorPrice and maximum == vendorPrice then + return vendorPrice, BrokerGarbage.tagVendor + + elseif auctionPrice and maximum == auctionPrice then + return auctionPrice, BrokerGarbage.tagAuction + + elseif disenchantPrice and maximum == disenchantPrice then + return disenchantPrice, BrokerGarbage.tagDisenchant + + else + return nil, nil end +end + +-- finds all occurences of the given item and returns the best location to delete from +function BrokerGarbage:FindSlotToDelete(itemID, ignoreFullStack) + local locations = {} + local maxStack = select(8, GetItemInfo(itemID)) - if vendorPrice then - if auctionPrice and disenchantPrice and DE then - if auctionPrice > disenchantPrice then - temp = auctionPrice - source = "|cFF9F9F5FA" -- greenish - else - temp = disenchantPrice - source = "|cFF7171C6DE" -- purple + local numSlots, freeSlots, ratio, bagType + for container = 0,4 do + numSlots = GetContainerNumSlots(container) + freeSlots, bagType = GetContainerFreeSlots(container) + if not numSlots or not freeSlots then break end + ratio = #freeSlots/numSlots + + for slot = 1, numSlots do + local _,count,locked,_,_,canOpen,itemLink = GetContainerItemInfo(container, slot) + + if itemLink and BrokerGarbage:GetItemID(itemLink) == itemID then + if not ignoreFullStack or (ignoreFullStack and count < maxStack) then + -- found one + table.insert(locations, { + slot = slot, + bag = container, + count = count, + ratio = ratio, + bagType = (bagType or 0) + }) + end end - elseif auctionPrice then - temp = auctionPrice - source = "|cFF9F9F5FA" -- greenish - else - temp = 0 end - - -- return highest price found - if vendorPrice > temp then - return vendorPrice * count, "|cFFF5DEB3V" -- orange + end + + -- recommend the location with the largest ratio that is NOT a specialty bag + table.sort(locations, function(a,b) + if a.bagType == 0 and b.bagType ~= 0 then + return true else - return temp * count or 0, source - end - else - return nil - end + -- return a.ratio > b.ratio + return a.count < b.count + end + end) + return locations end --- deletes the item in a given location of your bags. no questions asked +-- deletes the item in a given location of your bags. takes either link/bag/slot or an itemTable as created by GetCheapest() function BrokerGarbage:Delete(itemLink, bag, slot) if type(itemLink) == "table" then - bag = itemLink[2] - slot = itemLink[3] - itemLink = itemLink[1] + bag = itemLink[1].bag + slot = itemLink[1].slot + itemLink = select(2,GetItemInfo(itemLink[1].itemID)) end + -- security check + local itemID = GetContainerItemID(bag, slot) + if not select(2,GetItemInfo(itemID)) == itemLink then return end + PickupContainerItem(bag, slot) DeleteCursorItem() -- comment this line to prevent item deletion BG_GlobalDB.itemsDropped = BG_GlobalDB.itemsDropped + 1 @@ -684,75 +773,141 @@ end -- scans your inventory for possible junk items and updates LDB display function BrokerGarbage:ScanInventory() BrokerGarbage.inventory = {} - BrokerGarbage.toSellValue = 0 - local cheapestItem, freeSlots - local warnings = {} + BrokerGarbage.unopened = {} + local limitedItemsChecked = {} - local maxSpace = 0 -- will contain total number of inventory space - local freeSpace = 0 -- will contain total number of free bag space + BrokerGarbage.toSellValue = 0 + BrokerGarbage.totalBagSpace = 0 + BrokerGarbage.totalFreeSlots = 0 for container = 0,4 do local numSlots = GetContainerNumSlots(container) if numSlots then freeSlots = GetContainerFreeSlots(container) - freeSpace = freeSpace + (freeSlots and #freeSlots or 0) - maxSpace = maxSpace + GetContainerNumSlots(container) + BrokerGarbage.totalFreeSlots = BrokerGarbage.totalFreeSlots + (freeSlots and #freeSlots or 0) + BrokerGarbage.totalBagSpace = BrokerGarbage.totalBagSpace + numSlots - for slot = 1, GetContainerNumSlots(container) do + for slot = 1, numSlots do local itemID = GetContainerItemID(container,slot) if itemID then -- GetContainerItemInfo sucks big time ... just don't use it for quality IDs!!!!!!! - local _,count,locked,_,_,canOpen,itemLink = GetContainerItemInfo(container, slot) + local _,count,locked,_,_,_,itemLink = GetContainerItemInfo(container, slot) local quality = select(3,GetItemInfo(itemID)) + local isClam = BrokerGarbage:IsItem(itemID, BrokerGarbage.clams) - if canOpen and BG_GlobalDB.showWarnings then - tinsert(warnings, format(BrokerGarbage.locale.openPlease, - select(2,GetItemInfo(itemID)))) + if canOpen or isClam then + local _,_,_,_,_,type,subType,_,_,tex = GetItemInfo(itemID) + tinsert(BrokerGarbage.unopened, { + bag = container, + slot = slot, + itemID = itemID, + clam = isClam, + }) + if BG_GlobalDB.showWarnings then + local notice = format(BrokerGarbage.locale.openPlease, select(2,GetItemInfo(itemID))) + if not BrokerGarbage:Find(BrokerGarbage.warnings, notice) then + tinsert(BrokerGarbage.warnings, notice) + end + end end -- check if this item belongs to an excluded category - local inCategory, skip + local isExclude, skip for setName,_ in pairs(BrokerGarbage:JoinTables(BG_GlobalDB.exclude, BG_LocalDB.exclude)) do if type(setName) == "string" then - _, inCategory = BrokerGarbage.PT:ItemInSet(itemID, setName) + _, isExclude = BrokerGarbage.PT:ItemInSet(itemID, setName) end - -- item is on save list, skip - if inCategory then - skip = true - break + if isExclude then + skip = true; break end end - inCategory = nil - if not skip then - for setName,_ in pairs(BrokerGarbage:JoinTables(BG_GlobalDB.autoSellList, BG_LocalDB.autoSellList, BG_LocalDB.include, BG_GlobalDB.include)) do + + local isSell, isInclude + -- this saves excluded items + if not skip and not BG_GlobalDB.exclude[itemID] and not BG_LocalDB.exclude[itemID] then + local force = false + + -- check if item is in a category of Include List + for setName,_ in pairs(BrokerGarbage:JoinTables(BG_LocalDB.include, BG_GlobalDB.include)) do if type(setName) == "string" then - _, inCategory = BrokerGarbage.PT:ItemInSet(itemID, setName) + _, isInclude = BrokerGarbage.PT:ItemInSet(itemID, setName) end - if inCategory then inCategory = setName; break end + if isInclude then isInclude = setName; break end end - end - - if quality and - (quality <= BG_GlobalDB.dropQuality or inCategory - or BG_GlobalDB.include[itemID] or BG_LocalDB.include[itemID] - or BG_GlobalDB.autoSellList[itemID] or BG_LocalDB.autoSellList[itemID]) - and not BG_GlobalDB.exclude[itemID] and not BG_LocalDB.exclude[itemID] and not skip then -- save excluded items!!! - local force = false + -- check if item is in a category of Sell List + for setName,_ in pairs(BrokerGarbage:JoinTables(BG_GlobalDB.autoSellList, BG_LocalDB.autoSellList)) do + if type(setName) == "string" then + _, isSell = BrokerGarbage.PT:ItemInSet(itemID, setName) + end + if isSell then isSell = setName; break end + end + + -- ---------------------------------------------------------------------- + + -- get price and tag local value, source = BrokerGarbage:GetItemValue(itemLink,count) - -- make included items appear in tooltip list as "forced" - if BG_GlobalDB.include[itemID] or BG_LocalDB.include[itemID] - or BG_GlobalDB.include[inCategory] or BG_LocalDB.include[inCategory] then - if not value then value = 0 end + if isInclude or BG_GlobalDB.include[itemID] or BG_LocalDB.include[itemID] then + -- Include List item force = true - source = "|cFF8C1717I" -- overwrites former value, I as in "include" - end + + local limited = BrokerGarbage:Find(limitedItemsChecked, itemID) + if not limited then + if BG_GlobalDB.include[itemID] and type(BG_GlobalDB.include[itemID]) == "number" + or BG_LocalDB.include[itemID] and type(BG_LocalDB.include[itemID]) == "number" then + + -- this is a limited item - only check it once + tinsert(limitedItemsChecked, itemID) + limited = true + + local stackSize = select(8, GetItemInfo(itemID)) + local limit = tonumber(BG_GlobalDB.include[itemID]) or tonumber(BG_LocalDB.include[itemID]) + local saveStacks = ceil(limit/stackSize) + local locations = BrokerGarbage:FindSlotToDelete(itemID) + + if #locations > saveStacks then + local itemCount = 0 + for i = #locations, 1, -1 do + if itemCount < limit then + itemCount = itemCount + locations[i].count + else + tinsert(BrokerGarbage.inventory, { + bag = locations[i].bag, + slot = locations[i].slot, + itemID = itemID, + quality = quality, + count = locations[i].count, + value = 0, + source = BrokerGarbage.tagInclude, + force = force, + }) + end + end + end + end + end + + if not limited then + value = value or 0 + source = BrokerGarbage.tagInclude + else + value = nil + end + elseif isSell or BG_GlobalDB.autoSellList[itemID] or BG_LocalDB.autoSellList[itemID] then + -- AutoSell List item + value = select(11,GetItemInfo(itemID)) + source = BrokerGarbage.tagVendorList + + --elseif quality and quality <= BG_GlobalDB.dropQuality then + -- regular gray/junk treshold item + --force = false + end + if value then -- save if we have something sellable - if quality == 0 + if quality == 0 or isSell or BG_GlobalDB.autoSellList[itemID] or BG_LocalDB.autoSellList[itemID] then - BrokerGarbage:Debug("Added for selling:", itemID, GetItemInfo(itemID) or "") BrokerGarbage.toSellValue = BrokerGarbage.toSellValue + value end @@ -767,9 +922,6 @@ function BrokerGarbage:ScanInventory() force = force, } - if not cheapestItem or cheapestItem.value >= value then - cheapestItem = currentItem - end tinsert(BrokerGarbage.inventory, currentItem) end end @@ -778,14 +930,16 @@ function BrokerGarbage:ScanInventory() end end - if cheapestItem then + local cheapestItem = BrokerGarbage:GetCheapest() + + if cheapestItem ~= {} then LDB.text = format(BG_GlobalDB.LDBformat, - select(2,GetItemInfo(cheapestItem.itemID)), - cheapestItem.count, - BrokerGarbage:FormatMoney(cheapestItem.value), - freeSpace, - maxSpace) - BrokerGarbage.cheapestItem = cheapestItem + select(2,GetItemInfo(cheapestItem[1].itemID)), + cheapestItem[1].count, + BrokerGarbage:FormatMoney(cheapestItem[1].value), + BrokerGarbage.totalFreeSlots, + BrokerGarbage.totalBagSpace) + BrokerGarbage.cheapestItem = cheapestItem[1] else LDB.text = BrokerGarbage.locale.label BrokerGarbage.cheapestItem = nil @@ -797,10 +951,9 @@ end -- returns the n cheapest items in your bags in a table function BrokerGarbage:GetCheapest(number) if not number then number = 1 end - local cheapestItems = {} + local cheapestItems, temp = {}, {} -- get forced items - local count = 0 for _, itemTable in pairs(BrokerGarbage.inventory) do local skip = false @@ -808,15 +961,22 @@ function BrokerGarbage:GetCheapest(number) if usedTable == itemTable then skip = true end end - if not skip and itemTable.force and count < number then - tinsert(cheapestItems, itemTable) - count = count + 1 + if not skip and itemTable.force then + tinsert(temp, itemTable) end end - table.sort(cheapestItems, function(a, b) + table.sort(temp, function(a, b) return a.value < b.value end) + if #temp <= number then + cheapestItems = temp + else + for i = 1, number do + tinsert(cheapestItems, temp[i]) + end + end + -- fill with non-forced if #cheapestItems < number then local minPrice, minTable @@ -923,15 +1083,11 @@ function BrokerGarbage:AutoRepair() end end - -- Wishlist -- --------------------------------------------------------- +-- tooltip: if item has a count treshold set, don't show if we're below that treshold -- show lootable containers in your bag! make "open items" not as spammy -- increase/decrease loot treshold with mousewheel on LDB --- restack if necessary --- ask before deleting / treshold --- search list frames (similar to gnomishvendorshrinker) +-- restack if necessary -> PickupContainerItem // SplitContainerItem -- fubar_garbagefu: Soulbound, Quest, Bind on Pickup, Bind on Equip/Use. --- ignore special bags --- drop-beyond-treshold: only keep 5 soulshards --- feature: selective looting (only crafting materials, greens+ , ...) \ No newline at end of file +-- ignore special bags \ No newline at end of file diff --git a/deDE.lua b/deDE.lua index 434163c..a096b04 100644 --- a/deDE.lua +++ b/deDE.lua @@ -18,6 +18,8 @@ BrokerGarbage.locale = { itemDeleted = "%s wurde gelöscht.", openPlease = "Bitte öffne %s - es nimmt unnötig Platz weg.", + openClams = "Du hast eine %s im Inventar!", + couldNotLoot = "%s wurde nicht geplündert, da es zu billig ist.", slashCommandHelp = "Nutze |cffc0c0c0/garbage config|r um die Einstellungen zu öffnen oder |cffc0c0c0/garbage format |cffc0c0ffformatstring|r um das Format der LDB Anzeige anzupassen. |cffc0c0c0/garbage format reset|r setzt das LDB Format zurück. Für Statistiken, gib |cffc0c0c0/garbage stats|r ein.", statistics = "Statistik:\nGesamtverdienst (alle Charaktere): %1$s\nGesamtverlust (alle Charaktere): %2$s", @@ -119,7 +121,7 @@ BrokerGarbage.locale = { -- List Options Panel LOPTitle = "Positiv-Listen", - LOPSubTitle = "Um Items hinzuzufügen, ziehe sie auf das jeweilige '+'. Um sie zu entfernen, wähle sie aus und klicke auf '-'.", + LOPSubTitle = "Zum Hinzufügen ziehe Items auf das jeweilige '+'. Zum Entfernen wähle sie aus und klicke auf '-'. Nutze Kategorien per Rechts-Klick auf '+'.", -- Exclude List LOPExcludeHeader = "Ausschlussliste - Items hier werden nie verkauft/gelöscht.", @@ -137,10 +139,10 @@ BrokerGarbage.locale = { -- AutoSell Options Panel LONTitle = "Negativ-Listen", - LONSubTitle = "Um Items hinzuzufügen, ziehe sie auf das jeweilige '+'. Um sie zu entfernen, wähle sie aus und klicke auf '-'.", + LONSubTitle = "Analog zu den Positiv-Listen. Um eine maximale Anzahl für ein bestimmtes Item festzulegen, nutze das Mausrad über dem Item-Icon.", -- Include List - LONIncludeHeader = "Einschlussliste - Items hier werden mit als erstes im Tooltip gezeigt.", + LONIncludeHeader = "Einschlussliste - Items werden zuerst angezeigt und vom LM nicht geplündert.", LONIncludePlusTT = "Items hinzufügen, indem du sie hierher ziehst/hier ablegst. Rechtsklick, um Kategorien hinzuzufügen!", LONIncludeMinusTT = "Wähle Items, die du entfernen willst. Dann klicke hier.", LONIncludePromoteTT = "Klicke, um alle markierten Items in die globale Einschlussliste zu übernehmen.", @@ -155,7 +157,51 @@ BrokerGarbage.locale = { -- LibPeriodicTable texts PTCategoryTooltipHeader = "Kategorien hinzufügen", - PTCategoryTooltipText = "Füge Kategorien hinzu, indem du auf die entsprechenden Einträge clickst." + PTCategoryTooltipText = "Füge Kategorien hinzu, indem du auf die entsprechenden Einträge clickst.", + + -- Loot Manager + CreatureTypeBeast = "Wildtier", + Quest = "Quest", + You = "Ihr", + + LMTitle = "Loot Manager", + LMSubTitle = "Der Loot Manager kann den gesamten Lootvorgang verwalten, wenn du ihn lässt.\nHalte SHIFT beim Plündern lange gedrückt, wenn du sonst Autoloot an hast, aber einmalig 'per Hand' plündern möchtest.", + + LMEnableTitle = "Loot Manager aktivieren", + LMEnableTooltip = "Aktiviert den Loot Manager.", + + LMSelectiveTitle = "Selektives Looten", + LMSelectiveTooltip = "Wenn ausgewählt, entscheidet Broker_Garbage von selbst, welche Items gelootet werden.", + + LMAutoLootTitle = "Autoloot", + LMAutoLootTooltip = "Wenn nicht ausgewählt, wird Broker_Garbage nur bei bestimmten Gelegenheiten looten.", + + LMAutoLootSkinningTitle = "Kürschnern", + LMAutoLootSkinningTooltip = "Wenn ausgewählt, wird Broker_Garbage versuchen, durch dich kürschnerbare Kreaturen zu looten.", + + LMAutoLootPickpocketTitle = "Taschendiebstahl", + LMAutoLootPickpocketTooltip = "Wenn ausgewählt, wird Broker_Garbage automatisch plündern, wenn du ein Schurke in Verstohlenheit bist.", + + LMAutoLootFishingTitle = "Angeln", + LMAutoLootFishingTooltip = "Wenn ausgewählt, wird Broker_Garbage automatisch plündern, wenn du gerade angelst.", + + LMAutoDestroyTitle = "Auto-Zerstören", + LMAutoDestroyTooltip = "Wenn ausgewählt, wird Broker_Garbage bei zu wenig Platz versuchen, welchen zu schaffen.", + + LMFreeSlotsTitle = "Min. freier Inventarplatz", + LMFreeSlotsTooltip = "Setze das Minimum an freien Taschenplätzen, bei dem Broker_Garbage automatisch Platz schaffen soll.", + + LMRestackTitle = "Automatisch stapeln", + LMRestackTooltip = "Wenn ausgewählt, wird Broker_Garbage automatisch die von dir beobachteten Gegenstände nach dem Plündern stapeln, um Platz zu schaffen.", + + LMFullRestackTitle = "Gesamtes Inventar", + LMFullRestackTooltip = "Wenn ausgewählt, wird Broker_Garbage dein gesamtes Inventar zum Restacken beobachten.", + + LMOpenContainersTitle = "Warne: Behälter", + LMOpenContainersTooltip = "Wenn ausgewählt, wird Broker_Garbage eine Warnung ausgeben, solltest du ungeöffnete Behälter bei dir haben.", + + LMOpenClamsTitle = "Warne: Muscheln", + LMOpenClamsTooltip = "Wenn ausgewählt, wird Broker_Garbage eine Warnung ausgeben, wenn du ungeöffnete Muscheln im Inventar hast. Da diese aber nun stapelbar sind, verlierst du durch deaktivieren dieser Option keinen Taschenplatz.", } end \ No newline at end of file diff --git a/enUS.lua b/enUS.lua index 8d91a02..91a60d8 100644 --- a/enUS.lua +++ b/enUS.lua @@ -18,6 +18,8 @@ BrokerGarbage.locale = { itemDeleted = "%s has been deleted.", openPlease = "Please open your %s. It's in your bags, stealing your space!", + openClams = "You own a %s. Maybe consider opening it.", + couldNotLoot = "I did not loot %s because it's too cheap.", slashCommandHelp = "Use |cffc0c0c0/garbage config|r to open the config menu or |cffc0c0c0/garbage format |cc0c0c0ffformatstring|r to change the LDB display style or |cffc0c0c0/garbage format reset|r to reset it. For statistics type |cffc0c0c0/garbage stats|r.", statistics = "Statistics:\nTotal earnings (all characters): %1$s\nTotal losses (all characters): %2$s", @@ -119,7 +121,7 @@ BrokerGarbage.locale = { -- List Options Panel LOPTitle = "Positive Lists", - LOPSubTitle = "To add Items to lists, drag them over the corresponding '+' icon, to remove them select them and click the '-'.", + LOPSubTitle = "To add Items to lists, drag them over the corresponding '+' icon, to remove them select them and click the '-'. To add categories right-click on '+'.", -- Exclude List LOPExcludeHeader = "Exclude List - these items will never be sold/deleted.", @@ -137,10 +139,10 @@ BrokerGarbage.locale = { -- AutoSell Options Panel LONTitle = "Negative Lists", - LONSubTitle = "To add Items to lists, drag them over the corresponding '+' icon, to remove them select them and click the '-'.", + LONSubTitle = "Similar usage to Positive Lists. To set an item limit, use your mousewheel when over the item icon.", -- Include List - LONIncludeHeader = "Include List - these items will be shown first in the tooltip.", + LONIncludeHeader = "Include List - items will be shown first and not be looted by the Loot Manager.", LONIncludePlusTT = "Add items to the Exclude List by dragging/placing them on me. Right click on me for categories!", LONIncludeMinusTT = "Select items you want to remove, then click here.", LONIncludePromoteTT = "Selected items will be written onto your global Include List, as seen by every character.", @@ -155,6 +157,50 @@ BrokerGarbage.locale = { -- LibPeriodicTable texts PTCategoryTooltipHeader = "Add Categories", - PTCategoryTooltipText = "Navigate through this menu and add any of these categories by clicking on them." + PTCategoryTooltipText = "Navigate through this menu and add any of these categories by clicking on them.", + + -- Loot Manager + CreatureTypeBeast = "Beast", + Quest = "Quest", + You = "You", -- as in "You receive ..." + + LMTitle = "Loot Manager", + LMSubTitle = "The Loot Manager takes control of your looting if you want it to do so.\nIf you usually autoloot, hold down SHIFT for a while when looting a corpse to disable it once.", + + LMEnableTitle = "Enable Loot Manager", + LMEnableTooltip = "Check to enable the Loot Manager.", + + LMSelectiveTitle = "Selective Looting", + LMSelectiveTooltip = "Check to let Broker_Garbage determine which items to loot.", + + LMAutoLootTitle = "Autoloot", + LMAutoLootTooltip = "If unchecked, Broker_Garbage will only loot on special occations.", + + LMAutoLootSkinningTitle = "Skinning", + LMAutoLootSkinningTooltip = "If checked, Broker_Garbage will loot if the creature is skinnable by you.", + + LMAutoLootPickpocketTitle = "Pickpocket", + LMAutoLootPickpocketTooltip = "If checked, Broker_Garbage will loot if you are a Rogue and stealthed.", + + LMAutoLootFishingTitle = "Fishing", + LMAutoLootFishingTooltip = "If checked, Broker_Garbage will loot if you are currently fishing.", + + LMAutoDestroyTitle = "Autodestroy", + LMAutoDestroyTooltip = "If checked, Broker_Garbage will take actions when your inventory space is (almost) full.", + + LMFreeSlotsTitle = "Minimum free slots", + LMFreeSlotsTooltip = "Set the minimum numer of free slots for autodestroy to take action.", + + LMRestackTitle = "Automatic restack", + LMRestackTooltip = "Check to automatically compress your watched inventory items after looting.", + + LMFullRestackTitle = "Full inventory", + LMFullRestackTooltip = "When checked will look at your whole inventory for restackable items, not just the watched items.", + + LMOpenContainersTitle = "Warn: Containers", + LMOpenContainersTooltip = "When checked, Broker_Garbage will warn you when you have unopened containers in you inventory.", + + LMOpenClamsTitle = "Warn: Clams", + LMOpenClamsTooltip = "When checked, Broker_Garbage will warn you when you have clams in you inventory. As these now do stack, you are not wasting any slots by unchecking this.", } diff --git a/lootmanager.lua b/lootmanager.lua new file mode 100644 index 0000000..e1d505a --- /dev/null +++ b/lootmanager.lua @@ -0,0 +1,484 @@ +-- This is BrokerGarbage's Loot Manager - inspired by KarniCrap +-- It allows you to manage auto looting and dropping of "too many" items +_, BrokerGarbage = ... + +-- register events +local function eventHandler(self, event, ...) + if not BG_GlobalDB.useLootManager then return end + + if event == "CHAT_MSG_LOOT" then + if strfind(arg1, BrokerGarbage.locale.You) and BG_GlobalDB.autoDestroy then + BrokerGarbage:AutoDestroy() + end + + elseif event == "LOOT_OPENED" then + local numSlots = 0 + -- restack (relevant) inventory + if BG_GlobalDB.restackIfNeeded then + local justStacked = {} + if BG_GlobalDB.restackFullInventory then + for container = 0, 4 do + numSlots = GetContainerNumSlots(container) + if numSlots then + for slot = 1, numSlots do + local itemID = GetContainerItemID(container,slot) + if itemID and not BrokerGarbage:Find(justStacked, itemID) then + BrokerGarbage:Restack(itemID) + table.insert(justStacked, itemID) + end + end + end + end + else + for i, itemTable in pairs(BrokerGarbage.inventory) do + if not BrokerGarbage:Find(justStacked, itemTable.itemID) then + BrokerGarbage:Restack(itemTable.itemID) + table.insert(justStacked, itemTable.itemID) + end + end + end + end + -- looting + if BG_LocalDB.selectiveLooting then + local autoloot = arg1 + if BrokerGarbage.currentRestackItems ~= nil then + BrokerGarbage.afterRestack = function() + BrokerGarbage:SelectiveLooting(autoloot) + end + else + BrokerGarbage:SelectiveLooting(autoloot) + end + end + + elseif event == "LOOT_CLOSED" then + if BG_LocalDB.selectiveLooting then + BrokerGarbage:CheckAndClearInv() + end + + if BG_GlobalDB.openContainers then + BrokerGarbage:OpenContainers() + end + + elseif event == "ITEM_UNLOCKED" then + -- keep restacking + if BrokerGarbage:RestackStep() then + -- wait for next update + BrokerGarbage:Debug("Still restacking...", BrokerGarbage.currentRestackItems) + else + -- we're done + frame:UnregisterEvent("ITEM_UNLOCKED") + BrokerGarbage.currentRestackItems = nil + BrokerGarbage:Debug("Unregistered ITEM_UNLOCKED") + + if BrokerGarbage.afterRestack ~= nil then + BrokerGarbage:afterRestack() + BrokerGarbage.afterRestack = nil + end + end + end +end + +local frame = CreateFrame("Frame") +frame:RegisterEvent("CHAT_MSG_LOOT") +frame:RegisterEvent("LOOT_OPENED") +frame:RegisterEvent("LOOT_CLOSED") +frame:SetScript("OnEvent", eventHandler) + +-- --------------------------------------------------------- +-- Helper functions +-- --------------------------------------------------------- +-- restacks items so when deleting you lose as few items as possible +function BrokerGarbage:Restack(itemID) + if BrokerGarbage.currentRestackItems then + tinsert(BrokerGarbage.currentRestackItems, itemID) + else + BrokerGarbage.currentRestackItems = { itemID } + if BrokerGarbage:RestackStep() then + -- wait for moved items + frame:RegisterEvent("ITEM_UNLOCKED") + else + -- nothing to restack + if BrokerGarbage.afterRestack ~= nil then + BrokerGarbage:afterRestack() + BrokerGarbage.afterRestack = nil + end + end + end +end + +local function NextRestackStep() + -- go to next item if there is one + tremove(BrokerGarbage.currentRestackItems, 1) + if #(BrokerGarbage.currentRestackItems) <= 0 then + BrokerGarbage.currentRestackItems = nil + return false + else + return BrokerGarbage:RestackStep() + end +end + +-- move 1 item for restacking +function BrokerGarbage:RestackStep() + if not BrokerGarbage.currentRestackItems then return false end + local itemID = BrokerGarbage.currentRestackItems[1] + if not itemID then return NextRestackStep() end + + local count = GetItemCount(itemID) + if not count or count <= 1 then return NextRestackStep() end + + local locations = BrokerGarbage:FindSlotToDelete(itemID, true) + local maxLoc = #locations + if maxLoc <= 1 then + return NextRestackStep() + end -- we're done, nothing to restack + + if GetContainerItemInfo(locations[1].bag, locations[1].slot) then + ClearCursor() + PickupContainerItem(locations[1].bag, locations[1].slot) + PickupContainerItem(locations[maxLoc].bag, locations[maxLoc].slot) + + BrokerGarbage:Debug("Restack from/to", locations[1].count, locations[maxLoc].count) + end + return true +end + +-- calls restack and deletes as many items as needed +function BrokerGarbage:DeletePartialStack(itemID, num) + local locations = BrokerGarbage:FindSlotToDelete(itemID) + local maxStack = select(8, GetItemInfo(itemID)) + + SplitContainerItem(locations[1].bag, locations[1].slot, num) + if CursorHasItem() then + BrokerGarbage:Debug("DeletePartialStack", select(2,GetItemInfo(itemID)), num, locations[1].bag, locations[1].slot) + DeleteCursorItem() + end +end + +-- checks the inventory for items that can and should be dropped/restacked +function BrokerGarbage:CheckAndClearInv() + local numSlots + -- restack + local justStacked = {} + if BG_GlobalDB.restackIfNeeded and BG_GlobalDB.restackFullInventory then + for container = 0, 4 do + numSlots = GetContainerNumSlots(container) + if numSlots then + for slot = 1, numSlots do + local itemID = GetContainerItemID(container,slot) + if itemID and not BrokerGarbage:Find(justStacked, itemID) then + BrokerGarbage:Restack(itemID) + table.insert(justStacked, itemID) + end + end + end + end + elseif BG_GlobalDB.restackIfNeeded then + for i, itemTable in pairs(BrokerGarbage.inventory) do + if not BrokerGarbage:Find(justStacked, itemTable.itemID) then + BrokerGarbage:Restack(itemTable.itemID) + table.insert(justStacked, itemTable.itemID) + end + end + end + + -- drop until conditions are met + --while BrokerGarbage.totalFreeSlots <= BG_GlobalDB.tooFewSlots do + -- BrokerGarbage:Delete(BrokerGarbage:GetCheapest()) -- automatically takes included items + -- BrokerGarbage:ScanInventory() + --end +end + +-- drops Include List (Blacklist) items +function BrokerGarbage:AntiCrap() + local numSlots, itemID + for bag = 0, 4 do + numSlots = GetContainerNumSlots(container) + if numSlots then + for slot = 1, numSlots do + itemID = GetContainerItemID(container,slot) + if not IsInteresting(select(2,GetItemInfo(itemID))) then + BrokerGarbage:Delete(select(2,GetItemInfo(itemID)), bag, slot) + end + end + end + end +end + +-- warns of container - clams and/or containers +function BrokerGarbage:OpenContainers() + --[[if BrokerGarbage.totalFreeSlots < 2 then + BrokerGarbage:Print("Too few slots to securely loot containers! Please make some room.") + return + end]]-- + + -- only containers + if BG_GlobalDB.openContainers then + local itemLink + + for i, itemTable in pairs(BrokerGarbage.unopened) do + if not itemTable.clam then + itemLink = select(2,GetItemInfo(itemTable.itemID)) + BrokerGarbage:Print(format(BrokerGarbage.locale.openPlease, itemLink)) + -- UseContainerItem(itemTable.container, itemTable.slot) + tremove(BrokerGarbage.unopened, i) + end + end + end + + -- only clams + if BG_GlobalDB.openClams then + -- opening clams + local auctionType = select(6,GetAuctionItemClasses()) + local auctionSubType = GetAuctionItemSubClasses(6) + local itemLink + + for i, itemTable in pairs(BrokerGarbage.unopened) do + if itemTable.clam then + -- UseContainerItem(itemTable.bag, itemTable.slot) + itemLink = select(2,GetItemInfo(itemTable.itemID)) + BrokerGarbage:Print(format(BrokerGarbage.locale.openClams, itemLink)) + tremove(BrokerGarbage.unopened, i) + end + end + end +end + +--[[ returns number of free inventory slots // currently unused +function BrokerGarbage:GetNumSlots() + local total = 0 + local free = 0 + local numSlots = 0 + local freeSlots = 0 + + for container = 0, 4 do + freeSlots = select(1,GetContainerFreeSlots(container)) or {} + free = free + #freeSlots + numSlots = GetContainerNumSlots(container) + if numSlots then + total = total + numSlots + end + end + return total, free +end ]]-- + +-- returns true if the requested mob is skinnable with our skill +function BrokerGarbage:CanSkin(mobLevel) + local isSkinner = IsUsableSpell(select(1,GetSpellInfo(8613))) and BrokerGarbage:GetTradeSkill(select(1,GetSpellInfo(8613))) + if not isSkinner then return false end + local maxLevel + if isSkinner < 100 then + maxLevel = floor(isSkinner/10) + 10 + else + maxLevel = floor(isSkinner/5) + end + + return maxLevel >= mobLevel +end + +-- determines if an item should be lootet +function BrokerGarbage:IsInteresting(itemLink) + local itemID = BrokerGarbage:GetItemID(itemLink) + + local negativeList = BrokerGarbage:JoinTables(BG_GlobalDB.include, BG_LocalDB.include) + if negativeList[itemID] then + return false + else + -- check if the item belongs to a category + local inCategory + for setName,_ in pairs(negativeList) do + if type(setName) == "string" then + _, inCategory = BrokerGarbage.PT:ItemInSet(itemID, setName) + end + if inCategory then return false end + end + end + + return true + + --local positiveList = BrokerGarbage:JoinTables(BG_GlobalDB.exclude, BG_LocalDB.exclude) + --local sellList = BrokerGarbage:JoinTables(BG_GlobalDB.forceVendorPrice, BG_GlobalDB.autoSellList, BG_LocalDB.autoSellList) +end + +-- hook UpdateButton function for non-autoloot +local LootFrame_UpdateButton_orig = LootFrame_UpdateButton +function LootFrame_UpdateButton(index) + LootFrame_UpdateButton_orig(index) + + local slot = (LOOTFRAME_NUMBUTTONS * (LootFrame.page - 1)) + index + _, itemName, quantity, quality, locked = GetLootSlotInfo(slot) + itemLink = GetLootSlotLink(slot) + if not itemLink then return end + if BrokerGarbage:IsInteresting(itemLink) then + _G["LootButton"..index.."IconTexture"]:SetDesaturated(false) + _G["LootButton"..index.."IconTexture"]:SetAlpha(1) + else + _G["LootButton"..index.."IconTexture"]:SetDesaturated(true) + _G["LootButton"..index.."IconTexture"]:SetAlpha(0.5) + end +end + +-- --------------------------------------------------------- +-- lootmanager functionality from here +-- --------------------------------------------------------- +-- for use in CHAT_MSG_LOOT event - destroys watched items as needed +function BrokerGarbage:AutoDestroy() + local count + local location = {} + + for itemID,maxCount in pairs(BrokerGarbage:JoinTables(BG_LocalDB.include, BG_GlobalDB.include)) do + if type(itemID) == "number" and type(maxCount) == number then + count = GetItemCount(itemID) + + -- delete excess items + local i = 1 + location = BrokerGarbage:FindSlotToDelete(itemID) + while count > maxCount do + -- save the last stack, even if it itself is over our treshold (for stackable items) + if i == #location then break end + BrokerGarbage:Delete(GetItemInfo(itemID), location[i].bag, location[i].slot) + + count = GetItemCount(itemID) + i = i + 1 + end + end + end +end + +-- for use in LOOT_OPENED event +function BrokerGarbage:SelectiveLooting(autoloot) + if IsShiftKeyDown() then return end + local numItems = GetNumLootItems() + local texture, quantity, quality, locked, itemLink + local trouble, looted + local mobLevel = UnitExists("target") and UnitIsDead("target") and UnitLevel("target") + local mobType = UnitCreatureType("target") == BrokerGarbage.locale.CreatureTypeBeast + + if autoloot ~= 0 or BG_GlobalDB.autoLoot or (BG_GlobalDB.autoLootPickpocket and BrokerGarbage.playerClass == "ROGUE" and IsStealthed()) or (BG_GlobalDB.autoLootFishing and IsFishingLoot()) then + for slot = 1,numItems do + if LootSlotIsItem(slot) then + _, _, quantity, quality, locked = GetLootSlotInfo(slot) + itemLink = GetLootSlotLink(slot) + + -- check if we even want this! + if BrokerGarbage:IsInteresting(itemLink) then + if not locked then + if BrokerGarbage.totalFreeSlots <= BG_GlobalDB.tooFewSlots then + -- try to compress and make room + local itemID = BrokerGarbage:GetItemID(itemLink) + local maxStack = select(8, GetItemInfo(itemID)) + local inBags = mod(GetItemCount(itemID), maxStack) + local compareTo = BrokerGarbage:GetCheapest() + + if inBags > 0 and inBags + quantity > maxStack and BG_GlobalDB.autoDestroy then + -- we can fit x more in ... *squeeze* + local amount = quantity + inBags - maxStack + if compareTo[1] and (BrokerGarbage:GetItemValue(itemLink, (quantity-amount)) or 0) < compareTo[1].value then + BrokerGarbage:DeletePartialStack(itemID, amount) + BrokerGarbage:Debug("Item can be made to fit.", itemLink) + looted = true + end + elseif inBags > 0 then + -- this item fits without us doing anything + looted = true + end + + -- bad luck :/ maybe delete stuff that's worth less? always loot quest items + if BG_GlobalDB.autoDestroy and not looted and compareTo[1] + and ((BrokerGarbage:GetItemValue(itemLink, quantity) or 0) > compareTo[1].value + or select(6,GetItemInfo(itemLink)) == BrokerGarbage.locale.Quest) then + + BrokerGarbage:Delete(select(2,GetItemInfo(compareTo[1].itemID)), compareTo[1].bag, compareTo[1].slot) + LootSlot(slot) + elseif looted then + -- regular looting + LootSlot(slot) + else + -- something is in there, but not valuable enough for us to take it + BrokerGarbage:Print(format(BrokerGarbage.locale.couldNotLoot, itemLink)) + end + else + -- just loot normally + LootSlot(slot) + end + else + -- we should be able to loot this, but we are not. somebody set up us the bomb! + trouble = true + BrokerGarbage:Debug("Ooops! Something went wrong there. Item is locked", itemLink) + end + end + else + -- always take money + LootSlot(slot) + end + end + if (GetNumLootItems() ~= 0 and not trouble) or GetNumLootItems() == 0 then + CloseLoot() + end + + elseif BG_GlobalDB.autoLootSkinning and mobType and BrokerGarbage:CanSkin(mobLevel) then + -- clear the mob for skinning + BrokerGarbage:Debug("Clearing for Skinning") + + if numItems > BrokerGarbage.totalFreeSlots then + -- this might be too much for our inventory to take + for slot = 1,numItems do + if numItems > BrokerGarbage.totalFreeSlots then + _, _, quantity, quality, locked = GetLootSlotInfo(slot) + itemLink = GetLootSlotLink(slot) + + local itemID = BrokerGarbage:GetItemID(itemLink) + local maxStack = select(8, GetItemInfo(itemID)) + local inBags = mod(GetItemCount(itemID), maxStack) + local compareTo = BrokerGarbage:GetCheapest() + + if inBags > 0 and inBags + quantity <= maxStack then + -- it stacks + LootSlot(slot) + numItems = numItems - 1 + + elseif not IsInteresting(itemLink) then + -- loot and immediately destroy + LootSlot(slot) + numItems = numItems - 1 + if BG_GlobalDB.autoDestroy then BrokerGarbage:AntiCrap() end + + elseif BG_GlobalDB.autoDestroy then + if inBags > 0 and inBags + quantity > maxStack then + -- squeeze + local amount = quantity + inBags - maxStack + if compareTo[1] + and (BrokerGarbage:GetItemValue(itemLink, (quantity-amount)) or 0) < compareTo[1].value then + + BrokerGarbage:DeletePartialStack(itemID, amount) + LootSlot(slot) + numItems = numItems - 1 + else + -- must... delete... cheap... item + BrokerGarbage:Delete(compareTo) + LootSlot(slot) + numItems = numItems - 1 + end + else + -- must delete cheap item + BrokerGarbage:Delete(compareTo) + LootSlot(slot) + numItems = numItems - 1 + end + end + else + -- lucky, something stacked and there's no more trouble + LootSlot(slot) + numItems = numItems - 1 + end + end + + else + -- loot & check later + for slot = 1,numItems do + LootSlot(slot) + end + end + CloseLoot() + end +end +BrokerGarbage.lootManager = true \ No newline at end of file diff --git a/lootmanager_options.lua b/lootmanager_options.lua new file mode 100644 index 0000000..4e29f9b --- /dev/null +++ b/lootmanager_options.lua @@ -0,0 +1,196 @@ +_, BrokerGarbage = ... + +BrokerGarbage:CheckSettings() + +local function Update(self) + BrokerGarbage:lootManagerOptionsUpdate(self) +end + +local function ShowOptions(frame) + local title = LibStub("tekKonfig-Heading").new(BrokerGarbage.lootManagerOptions, "Broker_Garbage - " .. BrokerGarbage.locale.LMTitle) + + local subtitle = BrokerGarbage.lootManagerOptions:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") + subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8) + subtitle:SetPoint("RIGHT", BrokerGarbage.lootManagerOptions, -32, 0) + subtitle:SetHeight(45) + subtitle:SetNonSpaceWrap(true) + subtitle:SetJustifyH("LEFT") + subtitle:SetJustifyV("TOP") + subtitle:SetText(BrokerGarbage.locale.LMSubTitle) + + local enable = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMEnableTitle, "TOPLEFT", subtitle, "BOTTOMLEFT", -2, -4) + enable.tiptext = BrokerGarbage.locale.LMEnableTooltip + enable:SetChecked(BG_GlobalDB.useLootManager) + local checksound = enable:GetScript("OnClick") + enable:SetScript("OnClick", function(enable) + checksound(enable) + BG_GlobalDB.useLootManager = not BG_GlobalDB.useLootManager + Update() + end) + + -- -- Selective Looting ------------------------------------------------------- + local selective = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMSelectiveTitle, "TOPLEFT", enable, "BOTTOMLEFT", 14, -20) + selective.tiptext = BrokerGarbage.locale.LMSelectiveTooltip + selective:SetChecked(BG_LocalDB.selectiveLooting) + selective:SetScript("OnClick", function(selective) + checksound(selective) + BG_LocalDB.selectiveLooting = not BG_LocalDB.selectiveLooting + Update() + end) + + + local autoLoot = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMAutoLootTitle, "TOPLEFT", selective, "BOTTOMLEFT", 14, 0) + autoLoot.tiptext = BrokerGarbage.locale.LMAutoLootTooltip + autoLoot:SetChecked(BG_GlobalDB.autoLoot) + autoLoot:SetScript("OnClick", function(autoLoot) + checksound(autoLoot) + BG_GlobalDB.autoLoot = not BG_GlobalDB.autoLoot + Update() + end) + + local autoLoot_skinning = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMAutoLootSkinningTitle, "TOPLEFT", autoLoot, "BOTTOMLEFT", 14, 0) + autoLoot_skinning.tiptext = BrokerGarbage.locale.LMAutoLootSkinningTooltip + autoLoot_skinning:SetChecked(BG_GlobalDB.autoLootSkinning) + autoLoot_skinning:SetScript("OnClick", function(autoLoot_skinning) + checksound(autoLoot_skinning) + BG_GlobalDB.autoLootSkinning = not BG_GlobalDB.autoLootSkinning + end) + + local autoLoot_pickpocket = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMAutoLootPickpocketTitle, "TOPLEFT", autoLoot_skinning, "BOTTOMLEFT", 0, 0) + autoLoot_pickpocket.tiptext = BrokerGarbage.locale.LMAutoLootPickpocketTooltip + autoLoot_pickpocket:SetChecked(BG_GlobalDB.autoLootPickpocket) + autoLoot_pickpocket:SetScript("OnClick", function(autoLoot_pickpocket) + checksound(autoLoot_pickpocket) + BG_GlobalDB.autoLootPickpocket = not BG_GlobalDB.autoLootPickpocket + end) + + local autoLoot_fishing = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMAutoLootFishingTitle, "TOPLEFT", autoLoot_pickpocket, "BOTTOMLEFT", 0, 0) + autoLoot_fishing.tiptext = BrokerGarbage.locale.LMAutoLootFishingTooltip + autoLoot_fishing:SetChecked(BG_GlobalDB.autoLootPickpocket) + autoLoot_fishing:SetScript("OnClick", function(autoLoot_fishing) + checksound(autoLoot_fishing) + BG_GlobalDB.autoLootFishing = not BG_GlobalDB.autoLootFishing + end) + + + local autoDestroy = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMAutoDestroyTitle, "TOPLEFT", autoLoot_fishing, "BOTTOMLEFT", -14, 0) + autoDestroy.tiptext = BrokerGarbage.locale.LMAutoDestroyTooltip + autoDestroy:SetChecked(BG_GlobalDB.autoDestroy) + autoDestroy:SetScript("OnClick", function(autoDestroy) + checksound(autoDestroy) + BG_GlobalDB.autoDestroy = not BG_GlobalDB.autoDestroy + Update() + end) + + local minFreeSlots = LibStub("tekKonfig-Slider").new(BrokerGarbage.lootManagerOptions, BrokerGarbage.locale.LMFreeSlotsTitle, 0, 30, "TOPLEFT", autoDestroy, "BOTTOMLEFT", 14, -20) + minFreeSlots.tiptext = BrokerGarbage.locale.LMFreeSlotsTooltip + minFreeSlots:SetWidth(200) + minFreeSlots:SetValueStep(1) + minFreeSlots:SetValue(BG_GlobalDB.tooFewSlots) + minFreeSlots.text = minFreeSlots:CreateFontString("$parentCenterText", "ARTWORK", "GameFontHighlightSmall") + minFreeSlots.text:SetPoint("TOP", minFreeSlots, "BOTTOM", 0, 3) + minFreeSlots.text:SetText(BG_GlobalDB.tooFewSlots) + minFreeSlots:SetScript("OnValueChanged", function(minFreeSlots) + BG_GlobalDB.tooFewSlots = minFreeSlots:GetValue() + minFreeSlots.text:SetText(BG_GlobalDB.tooFewSlots) + BrokerGarbage:ScanInventory() + end) + + -- -- Restack ----------------------------------------------------------------- + local restack = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMRestackTitle, "TOPLEFT", selective, "TOPLEFT", 200, 0) + restack.tiptext = BrokerGarbage.locale.LMRestackTooltip + restack:SetChecked(BG_GlobalDB.restackIfNeeded) + restack:SetScript("OnClick", function(restack) + checksound(restack) + BG_GlobalDB.restackIfNeeded = not BG_GlobalDB.restackIfNeeded + Update() + end) + + local fullRestack = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMFullRestackTitle, "TOPLEFT", restack, "BOTTOMLEFT", 14, 0) + fullRestack.tiptext = BrokerGarbage.locale.LMFullRestackTooltip + fullRestack:SetChecked(BG_GlobalDB.restackFullInventory) + fullRestack:SetScript("OnClick", function(fullRestack) + checksound(fullRestack) + BG_GlobalDB.restackFullInventory = not BG_GlobalDB.restackFullInventory + end) + + -- -- Opening Items ----------------------------------------------------------- + local openContainers = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMOpenContainersTitle, "TOPLEFT", fullRestack, "BOTTOMLEFT", -14, -20) + openContainers.tiptext = BrokerGarbage.locale.LMOpenContainersTooltip + openContainers:SetChecked(BG_GlobalDB.openContainers) + openContainers:SetScript("OnClick", function(openContainers) + checksound(openContainers) + BG_GlobalDB.openContainers = not BG_GlobalDB.openContainers + end) + + local openClams = LibStub("tekKonfig-Checkbox").new(BrokerGarbage.lootManagerOptions, nil, BrokerGarbage.locale.LMOpenClamsTitle, "TOPLEFT", openContainers, "BOTTOMLEFT", 0, 0) + openClams.tiptext = BrokerGarbage.locale.LMOpenClamsTooltip + openClams:SetChecked(BG_GlobalDB.openClams) + openClams:SetScript("OnClick", function(openClams) + checksound(openClams) + BG_GlobalDB.openClams = not BG_GlobalDB.openClams + end) + + function BrokerGarbage.lootManagerOptionsUpdate(self) + if BG_GlobalDB.useLootManager then + restack:Enable() + if BG_GlobalDB.restackIfNeeded then + fullRestack:Enable() + else + fullRestack:Disable() + end + + openContainers:Enable() + openClams:Enable() + + selective:Enable() + if BG_LocalDB.selectiveLooting then + autoLoot:Enable() + autoDestroy:Enable() + + if not BG_GlobalDB.autoLoot then + autoLoot_skinning:Enable() + autoLoot_pickpocket:Enable() + autoLoot_fishing:Enable() + else + autoLoot_skinning:Disable() + autoLoot_pickpocket:Disable() + autoLoot_fishing:Disable() + end + + if BG_GlobalDB.autoDestroy then + minFreeSlots:Enable() + else + minFreeSlots:Disable() + end + else + autoLoot:Disable() + autoDestroy:Disable() + autoLoot_skinning:Disable() + autoLoot_pickpocket:Disable() + autoLoot_fishing:Disable() + minFreeSlots:Disable() + end + + else + restack:Disable() + fullRestack:Disable() + + openContainers:Disable() + openClams:Disable() + + selective:Disable() + autoLoot:Disable() + autoLoot_skinning:Disable() + autoLoot_pickpocket:Disable() + autoLoot_fishing:Disable() + autoDestroy:Disable() + minFreeSlots:Disable() + end + end + + BrokerGarbage:lootManagerOptionsUpdate() + BrokerGarbage.lootManagerOptions:SetScript("OnShow", BrokerGarbage.lootManagerOptionsUpdate) +end + +BrokerGarbage.lootManagerOptions:SetScript("OnShow", ShowOptions) \ No newline at end of file diff --git a/options.lua b/options.lua index 42165cf..88c64fe 100644 --- a/options.lua +++ b/options.lua @@ -4,13 +4,13 @@ BrokerGarbage:CheckSettings() -- rarity strings (no need to localize) BrokerGarbage.quality = { - [0] = "|cff9D9D9D"..ITEM_QUALITY0_DESC.."|r", - [1] = "|cffFFFFFF"..ITEM_QUALITY1_DESC.."|r", - [2] = "|cff1EFF00"..ITEM_QUALITY2_DESC.."|r", - [3] = "|cff0070FF"..ITEM_QUALITY3_DESC.."|r", - [4] = "|cffa335ee"..ITEM_QUALITY4_DESC.."|r", - [5] = "|cffff8000"..ITEM_QUALITY5_DESC.."|r", - [6] = "|cffE6CC80"..ITEM_QUALITY6_DESC.."|r", + [0] = select(4,GetItemQualityColor(0))..ITEM_QUALITY0_DESC.."|r", + [1] = select(4,GetItemQualityColor(1))..ITEM_QUALITY1_DESC.."|r", + [2] = select(4,GetItemQualityColor(2))..ITEM_QUALITY2_DESC.."|r", + [3] = select(4,GetItemQualityColor(3))..ITEM_QUALITY3_DESC.."|r", + [4] = select(4,GetItemQualityColor(4))..ITEM_QUALITY4_DESC.."|r", + [5] = select(4,GetItemQualityColor(5))..ITEM_QUALITY5_DESC.."|r", + [6] = select(4,GetItemQualityColor(6))..ITEM_QUALITY6_DESC.."|r", } -- create drop down menu table for PT sets @@ -54,10 +54,18 @@ BrokerGarbage.options:Hide() -- default / main options BrokerGarbage.basicOptions = CreateFrame("Frame", "BrokerGarbageOptionsPositiveFrame", InterfaceOptionsFramePanelContainer) -BrokerGarbage.basicOptions.name = "Basic Settings" +BrokerGarbage.basicOptions.name = BrokerGarbage.locale.BasicOptionsTitle BrokerGarbage.basicOptions.parent = "Broker_Garbage" BrokerGarbage.basicOptions:Hide() +-- Loot Manager options +if BrokerGarbage.lootManager then + BrokerGarbage.lootManagerOptions = CreateFrame("Frame", "BrokerGarbageOptionsFrame", InterfaceOptionsFramePanelContainer) + BrokerGarbage.lootManagerOptions.name = BrokerGarbage.locale.LMTitle + BrokerGarbage.lootManagerOptions.parent = "Broker_Garbage" + BrokerGarbage.lootManagerOptions:Hide() +end + -- list options: positive panel BrokerGarbage.listOptionsPositive = CreateFrame("Frame", "BrokerGarbageOptionsPositiveFrame", InterfaceOptionsFramePanelContainer) BrokerGarbage.listOptionsPositive.name = BrokerGarbage.locale.LOPTitle @@ -237,7 +245,7 @@ local function ShowOptions(frame) localmoneyinfo:SetNonSpaceWrap(true) localmoneyinfo:SetJustifyH("LEFT") localmoneyinfo:SetJustifyV("TOP") - localmoneyinfo:SetText(format(BrokerGarbage.locale.LocalStatisticsHeading, GetUnitName("player"))) + localmoneyinfo:SetText(format(BrokerGarbage.locale.LocalStatisticsHeading, UnitName("player"))) local localearned = BrokerGarbage.options:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall") localearned:SetWidth(150) @@ -283,6 +291,7 @@ local function ShowOptions(frame) globalreset:SetWidth(150) globalreset:SetScript("OnClick", function() BrokerGarbage:ResetAll(true) + UpdateStats() end) local localreset = LibStub("tekKonfig-Button").new(BrokerGarbage.options, "TOPLEFT", globalreset, "TOPRIGHT", 20, 0) @@ -291,6 +300,7 @@ local function ShowOptions(frame) localreset:SetWidth(150) localreset:SetScript("OnClick", function() BrokerGarbage:ResetAll(false) + UpdateStats() end) -- when panel is shown this will update the statistics data @@ -776,8 +786,52 @@ local function ShowListOptions(frame) emptyAutoSellList:SetNormalTexture("Interface\\Buttons\\Ui-grouploot-pass-up") emptyAutoSellList.tiptext = BrokerGarbage.locale.LONAutoSellEmptyTT - -- function that updates & shows items from various lists + -- function to set the drop treshold (limit) via the mousewheel + local function OnMouseWheel(self, dir) + if type(self.itemID) ~= "number" then return end + BrokerGarbage.debug = self + local list, text + + if dir == 1 then + -- up + if self.isGlobal then + list = BG_GlobalDB[self.list] + else + list = BG_LocalDB[self.list] + end + + -- change stuff + if list[self.itemID] == true then + list[self.itemID] = 1 + else + list[self.itemID] = list[self.itemID] + 1 + end + self.limit:SetText(list[self.itemID]) + + else + -- down + if self.isGlobal then + list = BG_GlobalDB[self.list] + else + list = BG_LocalDB[self.list] + end + + -- change stuff + if list[self.itemID] == true then + text = "" + elseif list[self.itemID] == 1 then + list[self.itemID] = true + text = "" + else + list[self.itemID] = list[self.itemID] - 1 + text = list[self.itemID] + end + self.limit:SetText(text) + end + end + local numCols = 8 + -- function that updates & shows items from various lists function BrokerGarbage:ListOptionsUpdate(listName) if not listName then BrokerGarbage:ListOptionsUpdate("include") @@ -850,10 +904,10 @@ local function ShowListOptions(frame) local itemLink, texture if type(itemID) ~= "number" then -- this is an item category - BrokerGarbage:Debug("Encountered Category String!", itemID) itemLink = nil button.tiptext = itemID -- category description string texture = "Interface\\Icons\\Trade_engineering" + else -- this is an explicit item _, itemLink, _, _, _, _, _, _, _, texture, _ = GetItemInfo(itemID) @@ -863,14 +917,18 @@ local function ShowListOptions(frame) -- everything's fine button.itemID = itemID button.itemLink = itemLink + button.isGlobal = globalList[itemID] or false + button.limit:SetText((button.isGlobal and globalList[itemID] ~= true and globalList[itemID]) + or (localList[itemID] ~= true and localList[itemID]) or "") button:SetNormalTexture(texture) - button:GetNormalTexture():SetDesaturated(globalList[itemID] or false) -- desaturate global list items + button:GetNormalTexture():SetDesaturated(button.isGlobal) -- desaturate global list items else -- an item the server has not seen button.itemID = itemID button.tiptext = "ID: "..itemID button:SetNormalTexture("Interface\\Icons\\Inv_misc_questionmark") end + button.list = listName button:SetChecked(false) button:Show() else @@ -880,6 +938,17 @@ local function ShowListOptions(frame) iconbutton:SetWidth(36) iconbutton:SetHeight(36) + local limit = iconbutton:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") + limit:SetPoint("BOTTOMLEFT", iconbutton, "BOTTOMLEFT", 2, 1) + limit:SetPoint("BOTTOMLEFT", iconbutton, "BOTTOMLEFT", 2, 1) + limit:SetPoint("BOTTOMRIGHT", iconbutton, "BOTTOMRIGHT", -3, 1) + limit:SetHeight(20) + limit:SetJustifyH("RIGHT") + limit:SetJustifyV("BOTTOM") + limit:SetText("") + + iconbutton.limit = limit + iconbutton:SetNormalTexture("Interface\\Icons\\Inv_misc_questionmark") iconbutton:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square") iconbutton:SetCheckedTexture("Interface\\Buttons\\UI-Button-Outline") @@ -889,9 +958,26 @@ local function ShowListOptions(frame) tex:SetPoint("CENTER") tex:SetWidth(36/37*66) tex:SetHeight(36/37*66) + iconbutton:SetScript("OnClick", function(self) + local check = self:GetChecked() + BrokerGarbage:Debug("OnClick", check) + + if IsModifiedClick("CHATLINK") and ChatFrameEditBox:IsVisible() then + -- post item link + ChatFrameEditBox:Insert(self.itemLink) + self:SetChecked(not check) + elseif not IsModifierKeyDown() then + self:SetChecked(check) + else + self:SetChecked(not check) + end + end) iconbutton:SetScript("OnEnter", ShowTooltip) iconbutton:SetScript("OnLeave", HideTooltip) - -- TODO: iconbutton:RegisterForClicks("Rightclick") + if listName == "include" then + iconbutton:EnableMouseWheel(true) + iconbutton:SetScript("OnMouseWheel", OnMouseWheel) + end if index == 1 then -- place first icon @@ -919,14 +1005,14 @@ local function ShowListOptions(frame) local function ItemDrop(self, item) local cursorType, itemID, link = GetCursorInfo() - if not cursorType == "item" and not item then + BrokerGarbage:Print("ItemDrop - "..(item or "").." ("..(link or "").."/"..(itemID or "")..")"..(cursorType or "")) + + if (not itemID and (item == "RightButton" or item == "LeftButton" or item == "MiddleButton")) then return end -- find the item we want to add - if item and item == "RightButton" then - return - elseif not item or item == "LeftButton" then + if itemID then -- real items itemID = itemID else @@ -1129,21 +1215,21 @@ local function ShowListOptions(frame) elseif self == promote then for i, button in pairs(BrokerGarbage.listButtons.exclude) do if button:GetChecked() then - BG_GlobalDB.exclude[button.itemID] = true + BG_GlobalDB.exclude[button.itemID] = BG_LocalDB.exclude[button.itemID] end end BrokerGarbage:ListOptionsUpdate("exclude") elseif self == promote3 then for i, button in pairs(BrokerGarbage.listButtons.include) do if button:GetChecked() then - BG_GlobalDB.include[button.itemID] = true + BG_GlobalDB.include[button.itemID] = BG_LocalDB.include[button.itemID] end end BrokerGarbage:ListOptionsUpdate("include") elseif self == promote3 then for i, button in pairs(BrokerGarbage.listButtons.autosell) do if button:GetChecked() then - BG_GlobalDB.autoSellList[button.itemID] = true + BG_GlobalDB.autoSellList[button.itemID] = BG_LocalDB.autoSellList[button.itemID] end end BrokerGarbage:ListOptionsUpdate("autosell") @@ -1233,6 +1319,7 @@ BrokerGarbage.listOptionsNegative:SetScript("OnShow", ShowListOptions) InterfaceOptions_AddCategory(BrokerGarbage.options) InterfaceOptions_AddCategory(BrokerGarbage.basicOptions) +InterfaceOptions_AddCategory(BrokerGarbage.lootManagerOptions) InterfaceOptions_AddCategory(BrokerGarbage.listOptionsPositive) InterfaceOptions_AddCategory(BrokerGarbage.listOptionsNegative) LibStub("tekKonfig-AboutPanel").new("Broker_Garbage", "Broker_Garbage") @@ -1259,6 +1346,20 @@ function SlashCmdList.BROKERGARBAGE(msg, editbox) elseif command == "options" or command == "config" or command == "option" or command == "menu" then InterfaceOptionsFrame_OpenToCategory(BrokerGarbage.options) + elseif command == "limit" or command == "glimit" or command == "globallimit" then + local itemID, count = rest:match("^[^0-9]-([0-9]+).-([0-9]+)$") + itemID = tonumber(itemID) + count = tonumber(count) + + if string.find(command, "g") then + BG_GlobalDB.include[itemID] = count + else + BG_LocalDB.include[itemID] = count + end + local itemLink = select(2,GetItemInfo(itemID)) + BrokerGarbage:Print(format("%s has been assigned a limit of %d.", itemLink, count)) + BrokerGarbage:ListOptionsUpdate("include") + else BrokerGarbage:Print(BrokerGarbage.locale.slashCommandHelp) end diff --git a/readme.txt b/readme.txt index 36e8dfc..1d15de8 100644 --- a/readme.txt +++ b/readme.txt @@ -1,7 +1,7 @@ Broker_Garbage ============== Author: ckaotik -Version: 3.3v16 +Version: 3.3v17 WoW Version: 3.3.2 (TOC 30300) WoWInterface: http://www.wowinterface.com/downloads/info15531-Broker_Garbage.html @@ -55,6 +55,7 @@ Items on this list will never have their auction value used. This is useful for * Include List Items on this list will be always be shown in the drop Tooltip, no matter what Quality Treshold you might have set. If you have too many, you won't see any other items in the tooltip. Caution! Grayed out items on there are items that are on your global list, active for all characters. Colorful ones are just for your current character. +Since 3.3v17 include list items also can have a limit set. Use this if for example you only want to keep 5 Soulshards. Excess items will be listed in the Tooltip! * Auto-Sell List Items on this list will be sold whenever you talk to a vendor. Items of higher quality than your Quality Treshold WILL be sold, just keep that in mind. @@ -87,7 +88,26 @@ Some examples: "%1$sx%2$d" -> [Hearthstone]x1 "%4$d/%5$d - %1$s" -> 18/48 - [Hearthstone] -8. How you can help +8. Slash Commands +----------------- +Broker_Garbage supports a hand full of slash commands. These are /garbage or short, /garb. Parameters supported: + + /garb format +See information on this one above, in part 7. + + /garb stats -or- /garb total -or- /garbage trash +Prints very simplified statistics to the chat frame. Further statistics/details can be found in the options menu. + + /garb option -or- /garb options -or- /garb menu -or- /garb config +All of these just open up the config window ;) + + /garb limit +This will add the corresponding item to the character's include list and add a limit to it. + + /garb glimit -or- /garb globallimit +Same as the above, just adds the item to the global include list. + +9. How you can help ----------------- I still need a few translations to get done. If you would like to help me with that, please do so on http://wow.curseforge.com/addons/broker_garbage/localization/ . Likewise, I need people to test the addon with different auction addons. If you have one that isn't yet supported, make a Feature Suggestion (see 4.). -- 1.7.9.5