diff --git a/LegionWA/AutoVendor/Event.lua b/LegionWA/AutoVendor/Event.lua index 9e1a87b..9641a43 100644 --- a/LegionWA/AutoVendor/Event.lua +++ b/LegionWA/AutoVendor/Event.lua @@ -2,12 +2,12 @@ function(allstates, e) if (GetMerchantNumItems() > 0) then aura_env.allstates = allstates - + if CanMerchantRepair() == true then RepairAllItems() end - + for container = 0, 4 do for slot = 1, C_Container.GetContainerNumSlots(container) do - aura_env.filterService:run(container, slot) + aura_env.FilterService.Run(container, slot) end end return true diff --git a/LegionWA/AutoVendor/Init.lua b/LegionWA/AutoVendor/Init.lua index d39f339..eacb450 100644 --- a/LegionWA/AutoVendor/Init.lua +++ b/LegionWA/AutoVendor/Init.lua @@ -1,92 +1,209 @@ local debug = false local iconDisplayDuration = 3 +---@param container number +---@param slot number +---@return string, string|nil local function getItemLink(container, slot) - return select(7, GetContainerItemInfo(container, slot)) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local link = select(7, C_Container.GetContainerItemInfo(container, slot)) + if link == nil then return "", string.format("C_Container.GetContainerItemInfo returned nil for link (arg 7)") end + return link end +---@param container number +---@param slot number +---@return string, string|nil local function getItemQuantity(container, slot) - return select(2, GetContainerItemInfo(container, slot)) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local quantity = select(2, C_Container.GetContainerItemInfo(container, slot)) + if quantity == nil then + return "", + string.format("C_Container.GetContainerItemInfo returned nil for quantity (arg 2)") + end + return quantity end +---@param container number +---@param slot number +---@return string, string|nil local function getItemName(container, slot) - return select(1, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local name = select(1, GetItemInfo(getItemLink(container, slot))) + if name == nil then return "", string.format("GetItemInfo returned nil for name (arg 1)") end + return name end +---@param container number +---@param slot number +---@return string, string|nil local function getItemType(container, slot) - return select(6, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local type = select(6, GetItemInfo(getItemLink(container, slot))) + if type == nil then return "", string.format("GetItemInfo returned nil for type (arg 6)") end + return type end +---@param container number +---@param slot number +---@return string, string|nil local function getItemSubtype(container, slot) - return select(7, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local subtype = select(7, GetItemInfo(getItemLink(container, slot))) + if subtype == nil then return "", string.format("GetItemInfo returned nil for subtype (arg 7)") end + return subtype end +---@param container number +---@param slot number +---@return string, string|nil local function getItemLevel(container, slot) - return select(4, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local level = select(4, GetItemInfo(getItemLink(container, slot))) + if level == nil then return "", string.format("GetItemInfo returned nil for level (arg 4)") end + return level end +---@param container number +---@param slot number +---@return string, string|nil local function getItemValue(container, slot) - return select(11, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local value = select(11, GetItemInfo(getItemLink(container, slot))) + if value == nil then return "", string.format("GetItemInfo returned nil for value (arg 11)") end + return value end +---@param container number +---@param slot number +---@return string, string|nil local function getItemQuality(container, slot) - return select(3, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local quality = select(3, GetItemInfo(getItemLink(container, slot))) + if quality == nil then return "", string.format("GetItemInfo returned nil for quality (arg 3)") end + return quality end +---@param container number +---@param slot number +---@return string, string|nil local function getItemEquipLocation(container, slot) - return select(9, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local equipLoc = select(9, GetItemInfo(getItemLink(container, slot))) + if equipLoc == nil then return "", string.format("GetItemInfo returned nil for equipLoc (arg 9)") end + return equipLoc end +---@param container number +---@param slot number +---@return string, string|nil local function getItemIcon(container, slot) - return select(10, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local icon = select(10, GetItemInfo(getItemLink(container, slot))) + if icon == nil then return "", string.format("GetItemInfo returned nil for icon (arg 10)") end + return icon end +---@param container number +---@param slot number +---@return string, string|nil local function getBindType(container, slot) - return select(14, GetItemInfo(getItemLink(container, slot))) + if container == nil then return "", string.format("Container is nil") end + if slot == nil then return "", string.format("Slot is nil") end + local bindType = select(14, GetItemInfo(getItemLink(container, slot))) + if bindType == nil then return "", string.format("GetItemInfo returned nil for bindType (arg 14)") end + return bindType end +---@class Filter +---@field requires table | nil +---@field filter fun(container: number, slot: number, provided: table): boolean +Filter = { + ---@param requires table | nil + ---@param filter fun(container: number, slot: number, provided: table): boolean + ---@return Filter + new = function(requires, filter) + local self = setmetatable({}, { + __index = Filter + }) + self.requires = requires + self.filter = filter + return self + end, - -local grayFilter = { - enabled = true, - filter = function(self, container, slot) - if (self.enabled) then - aura_env.debugLog("Gray filter; container = " .. container .. ", slot = " .. slot) - local itemQuality = getItemQuality(container, slot) - if (itemQuality and itemQuality == 0) then - aura_env.debugLog("Gray filter pass") - return true + ---@param self Filter + ---@param container number + ---@param slot number + ---@return boolean, string|nil + Run = function(self, container, slot) + ---@type table + local provided = {} + if self.requires then + for k, v in pairs(self.requires) do + local res, err = v(container, slot) + if err then + if debug then print(err) end + return false, err + end + provided[k] = res end end - end -} -local gearFilter = { - enabled = true, - ilvlThreshold = 850, - sellBoe = false, - filter = function(self, container, slot) - if (self.enabled) then - aura_env.debugLog("Gear filter; container = " .. container .. ", slot = " .. slot) - local itemLevel = getItemLevel(container, slot) - local itemBindType = getBindType(container, slot) - local itemType = getItemType(container, slot) - local itemEquipLoc = getItemEquipLocation(container, slot) - if (itemType and itemEquipLoc and - (itemType == "Armor" - or itemType == "Weapon" - or itemEquipLoc == "INVTYPE_FINGER" - or itemEquipLoc == "INVTYPE_TRINKET" - or itemEquipLoc == "INVTYPE_CLOAK" - or itemEquipLoc == "INVTYPE_NECK") - and itemLevel and itemBindType and itemLevel < self.ilvlThreshold and (itemBindType == 1 or self.sellBoe)) then - aura_env.debugLog("Gear filter pass") - return true - end + local res, err = self.filter(container, slot, provided) + if err then + if debug then print(err) end end + return res, nil end } +local grayFilter = Filter.new({ + ["quality"] = getItemQuality + }, + function(container, slot, provided) + if provided.quality == 0 then + return true + end + return false + end) +local gearFilter = Filter.new({ + ["ilvl"] = getItemLevel, + ["bindType"] = getBindType, + ["type"] = getItemType, + ["equipLoc"] = getItemEquipLocation + }, + function(container, slot, provided) + local ilvlThreshold = 850 + local sellBoe = false + + if provided.type == "Armor" + or provided.type == "Weapon" + or provided.equipLoc == "INVTYPE_FINGER" + or provided.equipLoc == "INVTYPE_TRINKET" + or provided.equipLoc == "INVTYPE_CLOAK" + or provided.equipLoc == "INVTYPE_NECK" then + if provided.ilvl < ilvlThreshold and (provided.bindType == 1 or sellBoe) then + return true + end + end + return false + end) + +---@param container number +---@param slot number +---@return nil, string|nil local function doSell(container, slot) - local itemIcon = getItemIcon(container, slot) - local itemName = getItemName(container, slot) - local itemQuantity = getItemQuantity(container, slot) - local itemQuality = getItemQuality(container, slot) + local itemIcon, err = getItemIcon(container, slot) + if err then return nil, string.format("Error getting item icon: %s", err) end + local itemName, err = getItemName(container, slot) + if err then return nil, string.format("Error getting item name: %s", err) end + local itemQuantity, err = getItemQuantity(container, slot) + if err then return nil, string.format("Error getting item quantity: %s", err) end + local itemQuality, err = getItemQuality(container, slot) + if err then return nil, string.format("Error getting item quality: %s", err) end - aura_env.debugLog("Drawing icon for " .. itemName .. " with quality " .. itemQuality) - local nameWithColor = aura_env.qualityColors[itemQuality + 1] .. "[" .. itemName .. "]\124r" - local nameWithQuantity = nameWithColor .. " x" .. itemQuantity + local nameWithColor = string.format("%s[%s]\124r", aura_env.qualityColors[itemQuality + 1], itemName) + local nameWithQuantity = string.format("%s x%s", nameWithColor, itemQuantity) - aura_env.debugLog("Assigning name" .. nameWithQuantity) aura_env.allstates[#aura_env.allstates + 1] = { show = true, changed = true, @@ -103,38 +220,37 @@ local function doSell(container, slot) autoHide = true, } - UseContainerItem(container, slot) + C_Container.UseContainerItem(container, slot) + return nil, nil end - -aura_env.filterService = { - filters = { - grayFilter, - gearFilter, - }, - slotsToLoot = {}, - run = function(self, container, slot) - aura_env.debugLog("Filtering item in container = " .. container .. ", slot = " .. slot .. "...") - if (not getItemLink(container, slot)) then - aura_env.debugLog("Slot empty") - return - end - for k, filter in pairs(self.filters) do - if (filter:filter(container, slot)) then - doSell(container, slot) - return - end - end - end +---@type table +local filters = { + grayFilter, + gearFilter } -aura_env.debugLog = function(obj) - if (debug) then - print(GetTime()) - DevTools_Dump(obj) - print() - end -end +---@class FilterService +aura_env.FilterService = { + ---@param container number + ---@param slot number + ---@return nil, nil + Run = function(container, slot) + local itemLink, err = getItemLink(container, slot) + if err then return nil, string.format("Err: slot empty (%d-%d) - %s", container, slot, err) end + for k, filter in pairs(filters) do + local res, err = filter:Run(container, slot) + if err then + if debug then print(err) end + else + if res then + doSell(container, slot) + return + end + end + end + end, +} aura_env.qualityColors = { "\124cff9d9d9d", -- Poor @@ -145,4 +261,4 @@ aura_env.qualityColors = { "\124cffff8000", -- Legendary "\124cffe6cc80", -- Artifact "\124cff00ccff", -- Heirloom -} \ No newline at end of file +}