165 lines
5.3 KiB
Lua
165 lines
5.3 KiB
Lua
-- Auto-sell items explicitly assigned by the user to the built-in Junk category.
|
|
-- Upstream Guda's vendor pass only sells poor-quality (gray) links, so a white,
|
|
-- green, etc. item manually moved to Junk is displayed as junk but never sold.
|
|
-- This module handles only those manual non-gray overrides; the original gray
|
|
-- junk seller remains unchanged.
|
|
|
|
local addon = Guda
|
|
|
|
local runner = CreateFrame("Frame")
|
|
runner:Hide()
|
|
runner.items = nil
|
|
runner.index = 0
|
|
runner.waitElapsed = 0
|
|
runner.pollElapsed = 0
|
|
runner.soldCount = 0
|
|
|
|
local function IsMerchantOpen()
|
|
return MerchantFrame and MerchantFrame:IsShown()
|
|
end
|
|
|
|
local function GetItemID(link)
|
|
if not link then return nil end
|
|
local Utils = addon.Modules and addon.Modules.Utils
|
|
if Utils and Utils.ExtractItemID then
|
|
return Utils:ExtractItemID(link)
|
|
end
|
|
local _, _, id = string.find(link, "item:(%d+)")
|
|
return id and tonumber(id) or nil
|
|
end
|
|
|
|
local function IsProtected(itemID)
|
|
local DB = addon.Modules and addon.Modules.DB
|
|
return DB and DB.IsItemProtected and DB:IsItemProtected(itemID)
|
|
end
|
|
|
|
local function IsManualJunk(itemID)
|
|
if not itemID then return false end
|
|
local CategoryManager = addon.Modules and addon.Modules.CategoryManager
|
|
if not CategoryManager or not CategoryManager.GetCategories then return false end
|
|
local cats = CategoryManager:GetCategories()
|
|
return cats and cats.itemOverrides and cats.itemOverrides[itemID] == "Junk"
|
|
end
|
|
|
|
local function IsGrayLink(link)
|
|
return link and string.find(link, "|cff9d9d9d") ~= nil
|
|
end
|
|
|
|
-- Wait for Guda's existing gray-junk seller to finish before starting this
|
|
-- pass, avoiding two vendor loops calling UseContainerItem in the same frame.
|
|
local function HasUnprotectedGrayJunk()
|
|
for bag = 0, 4 do
|
|
local numSlots = GetContainerNumSlots(bag) or 0
|
|
for slot = 1, numSlots do
|
|
local link = GetContainerItemLink(bag, slot)
|
|
if IsGrayLink(link) then
|
|
local itemID = GetItemID(link)
|
|
if itemID and not IsProtected(itemID) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function StopRunner()
|
|
runner:Hide()
|
|
runner.items = nil
|
|
runner.index = 0
|
|
runner.waitElapsed = 0
|
|
runner.pollElapsed = 0
|
|
runner.soldCount = 0
|
|
end
|
|
|
|
local function StartManualJunkSale()
|
|
local DB = addon.Modules and addon.Modules.DB
|
|
if not DB then return end
|
|
|
|
local autoVendor = DB:GetSetting("autoVendorJunk")
|
|
if autoVendor == nil then autoVendor = true end
|
|
if not autoVendor then return end
|
|
|
|
local items = {}
|
|
for bag = 0, 4 do
|
|
local numSlots = GetContainerNumSlots(bag) or 0
|
|
for slot = 1, numSlots do
|
|
local link = GetContainerItemLink(bag, slot)
|
|
-- Gray items are already handled by Guda's original vendor pass.
|
|
if link and not IsGrayLink(link) then
|
|
local itemID = GetItemID(link)
|
|
if itemID and IsManualJunk(itemID) and not IsProtected(itemID) then
|
|
local _, _, locked = GetContainerItemInfo(bag, slot)
|
|
if not locked then
|
|
table.insert(items, { bag = bag, slot = slot, itemID = itemID })
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if table.getn(items) == 0 then return end
|
|
|
|
runner.items = items
|
|
runner.index = 0
|
|
runner.waitElapsed = 0
|
|
runner.pollElapsed = 0
|
|
runner.soldCount = 0
|
|
runner:Show()
|
|
end
|
|
|
|
runner:SetScript("OnUpdate", function()
|
|
if not IsMerchantOpen() then
|
|
StopRunner()
|
|
return
|
|
end
|
|
|
|
-- Poll at 10 Hz while the original gray-item seller is active. A hard
|
|
-- two-second ceiling prevents a stuck/locked gray item from blocking the
|
|
-- manual-junk pass forever.
|
|
if this.waitElapsed < 2.0 then
|
|
this.waitElapsed = this.waitElapsed + arg1
|
|
this.pollElapsed = this.pollElapsed + arg1
|
|
if this.pollElapsed < 0.10 then return end
|
|
this.pollElapsed = 0
|
|
if HasUnprotectedGrayJunk() then return end
|
|
this.waitElapsed = 2.0
|
|
end
|
|
|
|
this.index = this.index + 1
|
|
local item = this.items and this.items[this.index]
|
|
if not item then
|
|
if this.soldCount > 0 then
|
|
addon:Debug("Sold %d manually assigned junk item(s)", this.soldCount)
|
|
end
|
|
StopRunner()
|
|
return
|
|
end
|
|
|
|
-- Revalidate the slot immediately before selling. This protects against
|
|
-- inventory changes while the merchant window is open.
|
|
local link = GetContainerItemLink(item.bag, item.slot)
|
|
local itemID = GetItemID(link)
|
|
if link and itemID == item.itemID and not IsGrayLink(link)
|
|
and IsManualJunk(itemID) and not IsProtected(itemID) then
|
|
local _, _, locked = GetContainerItemInfo(item.bag, item.slot)
|
|
if not locked then
|
|
UseContainerItem(item.bag, item.slot)
|
|
this.soldCount = this.soldCount + 1
|
|
end
|
|
end
|
|
end)
|
|
|
|
local eventFrame = CreateFrame("Frame")
|
|
eventFrame:RegisterEvent("MERCHANT_SHOW")
|
|
eventFrame:RegisterEvent("MERCHANT_CLOSED")
|
|
eventFrame:SetScript("OnEvent", function()
|
|
if event == "MERCHANT_SHOW" then
|
|
StartManualJunkSale()
|
|
elseif event == "MERCHANT_CLOSED" then
|
|
StopRunner()
|
|
end
|
|
end)
|
|
|
|
addon:Debug("Manual Junk auto-sell compatibility fix loaded")
|