local TSM = select(2, ...) local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Shopping") -- loads the localization table local private = {itemOperations={}, purchasedCounts={}} local function GetActiveOperations(itemString, operations) if not operations or #operations == 0 then return end local totalQty = TSM:GetTotalQuantity(itemString) or 0 totalQty = totalQty + (private.purchasedCounts[itemString] or 0) local active = {} for _, opName in ipairs(operations) do TSMAPI:UpdateOperation("Shopping", opName) local opSettings = TSM.operations[opName] if opSettings then local maxRestock = tonumber(opSettings.maxRestock) or 0 if maxRestock <= 0 or totalQty < maxRestock then tinsert(active, opSettings) end end end return active end function private.Create(parent) local frame = CreateFrame("Frame", nil, parent) frame:SetAllPoints() local stContainer = CreateFrame("Frame", nil, frame) stContainer:SetPoint("TOPLEFT", 0, -35) stContainer:SetPoint("BOTTOMRIGHT", 0, 30) TSMAPI.Design:SetFrameColor(stContainer) frame.groupTree = TSMAPI:CreateGroupTree(stContainer, "Shopping", "Shopping_AH") private.groupTree = frame.groupTree local helpText = TSMAPI.GUI:CreateLabel(frame) helpText:SetPoint("TOPLEFT") helpText:SetPoint("TOPRIGHT") helpText:SetHeight(35) helpText:SetJustifyH("CENTER") helpText:SetJustifyV("CENTER") helpText:SetText(L["Select the groups which you would like to include in the search."]) frame.helpText = helpText local startBtn = TSMAPI.GUI:CreateButton(frame, 16) startBtn:SetPoint("BOTTOMLEFT", 3, 3) startBtn:SetPoint("BOTTOMRIGHT", -3, 3) startBtn:SetHeight(20) startBtn:SetText(L["Start Search"]) startBtn:SetScript("OnClick", private.StartScan) frame.startBtn = startBtn return frame end function private.ScanCallback(event, ...) if event == "filter" then local filter = ... local maxPrice for _, itemString in ipairs(filter.items) do local operations = GetActiveOperations(itemString, private.itemOperations[itemString]) if not operations or #operations == 0 then return end local itemMaxPrice for _, operation in ipairs(operations) do if operation.showAboveMaxPrice then itemMaxPrice = nil break end local operationPrice = TSM:GetMaxPrice(operation.maxPrice, itemString) if operationPrice then itemMaxPrice = itemMaxPrice and max(itemMaxPrice, operationPrice) or operationPrice end end if itemMaxPrice == nil then maxPrice = nil break end if not itemMaxPrice then return end maxPrice = maxPrice and max(maxPrice, itemMaxPrice) or itemMaxPrice end return maxPrice elseif event == "process" then local itemString, auctionItem = ... -- filter out auctions according to operation settings itemString = TSMAPI:GetBaseItemString(itemString, true) local operations = GetActiveOperations(itemString, private.itemOperations[itemString]) if not operations or #operations == 0 then return end auctionItem:FilterRecords(function(record) local buyout = record:GetItemBuyout() or 0 local totalQty = TSM:GetTotalQuantity(itemString) or 0 totalQty = totalQty + (private.purchasedCounts[itemString] or 0) for _, operation in ipairs(operations) do local maxRestock = tonumber(operation.maxRestock) or 0 if maxRestock > 0 and (totalQty + record.count) > maxRestock then -- this operation can't accept more of this item elseif operation.evenStacks and record.count % 5 ~= 0 then -- not an even stack for this operation elseif operation.showAboveMaxPrice then return false else local operationPrice = TSM:GetMaxPrice(operation.maxPrice, itemString) if operationPrice and buyout <= operationPrice then return false end end end return true end) local marketValue for _, operation in ipairs(operations) do local operationPrice = TSM:GetMaxPrice(operation.maxPrice, itemString) if operationPrice then marketValue = marketValue and max(marketValue, operationPrice) or operationPrice end end auctionItem:SetMarketValue(marketValue) return auctionItem elseif event == "done" then TSM.Search:SetSearchBarDisabled(false) return end end function private.StartScan() TSMAPI:FireEvent("SHOPPING:GROUPS:STARTSCAN") wipe(private.itemOperations) wipe(private.purchasedCounts) TSM.searchCallback = function(event, auction) if event == "OnBuyout" and auction then local linkItemString = auction.link and TSMAPI:GetItemString(auction.link) if linkItemString then local itemString = TSMAPI:GetBaseItemString(linkItemString, true) private.purchasedCounts[itemString] = (private.purchasedCounts[itemString] or 0) + (auction.count or 0) end end end TSM.groupBuyoutCheck = function(itemString, count, buyoutPerItem) itemString = TSMAPI:GetBaseItemString(itemString, true) local operations = GetActiveOperations(itemString, private.itemOperations[itemString]) if not operations or #operations == 0 then return false end for _, operation in ipairs(operations) do local maxRestock = tonumber(operation.maxRestock) or 0 local totalQty = TSM:GetTotalQuantity(itemString) or 0 totalQty = totalQty + (private.purchasedCounts[itemString] or 0) if maxRestock > 0 and (totalQty + count) > maxRestock then -- doesn't fit this operation elseif operation.evenStacks and count % 5 ~= 0 then -- not an even stack for this operation elseif operation.showAboveMaxPrice then return true else local operationPrice = TSM:GetMaxPrice(operation.maxPrice, itemString) if operationPrice and buyoutPerItem and buyoutPerItem > 0 and buyoutPerItem <= operationPrice then return true end end end return false end for groupName, data in pairs(private.groupTree:GetSelectedGroupInfo()) do groupName = TSMAPI:FormatGroupPath(groupName, true) for _, opName in ipairs(data.operations) do TSMAPI:UpdateOperation("Shopping", opName) local opSettings = TSM.operations[opName] if not opSettings then -- operation doesn't exist anymore in Auctioning TSM:Printf(L["'%s' has a Shopping operation of '%s' which no longer exists. Shopping will ignore this group until this is fixed."], groupName, opName) else -- it's a valid operation for itemString in pairs(data.items) do local baseItemString = TSMAPI:GetBaseItemString(itemString, true) or itemString local _, err = TSM:GetMaxPrice(opSettings.maxPrice, itemString) if err then TSM:Printf(L["Invalid custom price source for %s. %s"], TSMAPI:GetSafeItemInfo(itemString) or itemString, err) else local totalQty = TSM:GetTotalQuantity(itemString) or 0 local maxRestock = tonumber(opSettings.maxRestock) or 0 if maxRestock <= 0 or totalQty < maxRestock then private.itemOperations[baseItemString] = private.itemOperations[baseItemString] or {} tinsert(private.itemOperations[baseItemString], opName) end end end end end end local itemList = {} for itemString in pairs(private.itemOperations) do tinsert(itemList, itemString) end TSM.Search:SetSearchBarDisabled(true) TSM.Util:ShowSearchFrame(nil, L["% Max Price"]) TSM.Util:StartItemScan(itemList, private.ScanCallback) end do TSM:AddSidebarFeature(L["TSM Groups"], private.Create) end