yellowfive@161: local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") yellowfive@161: local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) yellowfive@161: local AceGUI = LibStub("AceGUI-3.0") yellowfive@161: yellowfive@161: local _frameJunk yellowfive@161: local _lblAction yellowfive@161: local _lblBank yellowfive@161: local _btnBank yellowfive@161: local _panelContent yellowfive@161: yellowfive@161: local _canDisenchant = false yellowfive@161: local _isScrapOpen = false yellowfive@161: local _isMerchantOpen = false yellowfive@161: local _isBankOpen = false yellowfive@161: yellowfive@161: -- yellowfive@161: -- Scan a bag for the specified item, returning the first exact match found yellowfive@161: -- yellowfive@161: local function scanBag(bagId, matchItem, usedItems) yellowfive@161: yellowfive@161: local numSlots = GetContainerNumSlots(bagId) yellowfive@161: local loc = ItemLocation.CreateEmpty() yellowfive@161: yellowfive@161: if not usedItems[bagId] then yellowfive@161: usedItems[bagId] = {} yellowfive@161: end yellowfive@161: yellowfive@163: local bestMatchDiffs = 1000000 yellowfive@163: local bestMatch = nil yellowfive@163: local threshold yellowfive@163: yellowfive@161: for slotId = 1, numSlots do yellowfive@161: if not usedItems[bagId][slotId] then yellowfive@161: local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) yellowfive@161: if itemLink ~= nil then yellowfive@161: local itemData = Amr.Serializer.ParseItemLink(itemLink) yellowfive@161: if itemData ~= nil then yellowfive@161: -- see if this is an azerite item and read azerite power ids yellowfive@161: loc:SetBagAndSlot(bagId, slotId) yellowfive@161: if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then yellowfive@161: local powers = Amr.ReadAzeritePowers(loc) yellowfive@161: if powers then yellowfive@161: itemData.azerite = powers yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: -- see if it matches yellowfive@163: local diffs = Amr.CountItemDifferences(matchItem, itemData) yellowfive@163: if diffs == 0 then yellowfive@161: usedItems[bagId][slotId] = true yellowfive@161: itemData.bagId = bagId yellowfive@161: itemData.slotId = slotId yellowfive@161: return itemData yellowfive@163: elseif diffs < 10000 then yellowfive@163: if itemData.azerite and #itemData.azerite > 0 then yellowfive@163: threshold = 100 yellowfive@163: else yellowfive@163: threshold = 10000 yellowfive@163: end yellowfive@163: if diffs < threshold and diffs < bestMatchDiffs then yellowfive@163: -- closest match we could find yellowfive@163: bestMatchDiffs = diffs yellowfive@163: itemData.bagId = bagId yellowfive@163: itemData.slotId = slotId yellowfive@163: bestMatch = itemData yellowfive@163: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@163: yellowfive@163: -- if we couldn't get a perfect match, take the best match that might have some small differences like yellowfive@163: -- an old school enchant or upgrade ID that didn't load yellowfive@163: if bestMatch then yellowfive@163: usedItems[bestMatch.bagId][bestMatch.slotId] = true yellowfive@163: return bestMatch yellowfive@163: else yellowfive@163: return nil yellowfive@163: end yellowfive@161: end yellowfive@161: yellowfive@161: -- yellowfive@161: -- Find a matching item in the player's bags yellowfive@161: -- yellowfive@161: local function findMatchingBagItem(item, usedItems) yellowfive@161: yellowfive@161: local matchItem = scanBag(BACKPACK_CONTAINER, item, usedItems) -- backpack yellowfive@161: if not matchItem then yellowfive@161: for bagId = 1, NUM_BAG_SLOTS do yellowfive@161: matchItem = scanBag(bagId, item, usedItems) yellowfive@161: if matchItem then break end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: return matchItem yellowfive@161: end yellowfive@161: yellowfive@161: yellowfive@161: -- yellowfive@161: -- item actions yellowfive@161: -- yellowfive@161: local _deSpellName = GetSpellInfo(13262); yellowfive@161: local _deMacro = "/stopmacro [combat][btn:2]\n/stopcasting\n/cast %s\n/use %s %s"; yellowfive@161: yellowfive@161: local function onItemPreClick(widget) yellowfive@161: yellowfive@161: local item = widget:GetUserData("itemData") yellowfive@161: yellowfive@161: if item and _canDisenchant and (not _isScrapOpen and not _isMerchantOpen) then yellowfive@161: -- only way i can find to disenchant and item on click is to call a macro, gross but works yellowfive@161: local matchItem = findMatchingBagItem(item, {}) yellowfive@161: if matchItem then yellowfive@161: widget:SetMacroText(_deMacro:format(_deSpellName, matchItem.bagId, matchItem.slotId)) yellowfive@161: else yellowfive@161: widget:SetMacroText(nil) yellowfive@161: Amr:Print(L.JunkItemNotFound) yellowfive@161: end yellowfive@161: else yellowfive@161: widget:SetMacroText(nil) yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: local function onItemClick(widget) yellowfive@161: yellowfive@161: local item = widget:GetUserData("itemData") yellowfive@161: if not item then return end yellowfive@161: yellowfive@161: local action = nil yellowfive@161: if _isScrapOpen then yellowfive@161: action = "scrap" yellowfive@161: elseif _isMerchantOpen then yellowfive@161: action = "sell" yellowfive@161: elseif _canDisenchant then yellowfive@161: action = "disenchant" yellowfive@161: end yellowfive@161: yellowfive@161: if not action then return end yellowfive@161: yellowfive@161: local matchItem = findMatchingBagItem(item, {}) yellowfive@161: if matchItem then yellowfive@161: if action == "scrap" then yellowfive@161: UseContainerItem(matchItem.bagId, matchItem.slotId) yellowfive@161: elseif action == "sell" then yellowfive@161: UseContainerItem(matchItem.bagId, matchItem.slotId) yellowfive@161: end yellowfive@161: yellowfive@161: -- note for disenchant, the macro has handled the action, this will simply remove the item from the list yellowfive@161: yellowfive@161: -- re-render the list with this item removed; yellowfive@161: -- AceGUI doesn't give a good way to remove a ui element from a container and re-render, yellowfive@161: -- so we sort of hack it and modify the collection of children directly, yellowfive@161: -- avoids the expensive logic of finding and matching all the items when the list changes as a user sells stuff yellowfive@161: local scroll = widget.parent.parent yellowfive@161: local newChildren = {} yellowfive@161: for i = 1, #scroll.children do yellowfive@161: local child = scroll.children[i] yellowfive@161: if child ~= widget.parent then yellowfive@161: table.insert(newChildren, child) yellowfive@161: end yellowfive@161: end yellowfive@161: scroll.children = newChildren yellowfive@161: yellowfive@161: -- dispose the item just removed, then re-render the list yellowfive@161: widget.parent:Release() yellowfive@161: widget.parent.parent:DoLayout() yellowfive@161: else yellowfive@161: Amr:Print(L.JunkItemNotFound) yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: yellowfive@161: -- yellowfive@161: -- bank withdraw stuff yellowfive@161: -- yellowfive@161: local _bankUsedBagSlots = nil yellowfive@161: local finishBankWithdraw yellowfive@161: local doBankWithdraw yellowfive@161: yellowfive@161: finishBankWithdraw = function() yellowfive@161: yellowfive@161: local done = true yellowfive@161: yellowfive@161: if _isBankOpen and _bankUsedBagSlots then yellowfive@161: for bagId,v in pairs(_bankUsedBagSlots) do yellowfive@161: for slotId,v in pairs(v) do yellowfive@161: local _, _, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) yellowfive@161: if not itemLink then yellowfive@161: done = false yellowfive@161: break yellowfive@161: end yellowfive@161: end yellowfive@161: if not done then break end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: if not done then yellowfive@161: -- wait a second and try again yellowfive@161: Amr.Wait(1, function() yellowfive@161: doBankWithdraw() yellowfive@161: end) yellowfive@161: else yellowfive@161: yellowfive@161: -- reset state yellowfive@161: _bankUsedBagSlots = nil yellowfive@161: _btnBank:SetDisabled(not _isBankOpen) yellowfive@161: yellowfive@161: -- re-render the junk list yellowfive@161: Amr:RefreshJunkUi() yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: doBankWithdraw = function() yellowfive@161: if not _isBankOpen then return end yellowfive@161: yellowfive@161: local data = Amr.db.char.JunkData yellowfive@161: if not data.Junk then return end yellowfive@161: yellowfive@161: -- disable button while processing yellowfive@161: _btnBank:SetDisabled(true) yellowfive@161: yellowfive@161: local bagList = {} yellowfive@161: table.insert(bagList, BANK_CONTAINER) yellowfive@161: for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do yellowfive@161: table.insert(bagList, bagId) yellowfive@161: end yellowfive@161: yellowfive@161: local usedItems = {} yellowfive@161: _bankUsedBagSlots = {} yellowfive@161: yellowfive@161: for i,item in ipairs(data.Junk) do yellowfive@161: -- stop immediately if the bank is closed yellowfive@161: if not _isBankOpen then yellowfive@161: finishBankWithdraw() yellowfive@161: return yellowfive@161: end yellowfive@161: yellowfive@161: -- check if already in bags yellowfive@161: local matchItem = findMatchingBagItem(item, usedItems) yellowfive@161: if not matchItem then yellowfive@161: -- find it in the bank yellowfive@161: for j = 1, #bagList do yellowfive@161: matchItem = scanBag(bagList[j], item, usedItems) yellowfive@161: if matchItem then break end yellowfive@161: end yellowfive@161: else yellowfive@161: matchItem = nil yellowfive@161: end yellowfive@161: yellowfive@161: if matchItem then yellowfive@161: -- move it to the player's bags if there is space yellowfive@161: local bagId, slotId = Amr.FindFirstEmptyBagSlot(_bankUsedBagSlots) yellowfive@161: if bagId then yellowfive@161: UseContainerItem(matchItem.bagId, matchItem.slotId) yellowfive@161: else yellowfive@161: -- no more empty bag slots yellowfive@161: break yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: -- wait a second and see if all the moves actually finished yellowfive@161: Amr.Wait(1, function() yellowfive@161: finishBankWithdraw() yellowfive@161: end) yellowfive@161: end yellowfive@161: yellowfive@161: local function onBankClick() yellowfive@161: if not _frameJunk or not _isBankOpen then return end yellowfive@161: yellowfive@161: doBankWithdraw() yellowfive@161: end yellowfive@161: yellowfive@161: yellowfive@161: local function onJunkFrameClose(widget) yellowfive@161: AceGUI:Release(widget) yellowfive@161: _frameJunk = nil yellowfive@161: _lblAction = nil yellowfive@161: _lblBank = nil yellowfive@161: _btnBank = nil yellowfive@161: _panelContent = nil yellowfive@161: end yellowfive@161: yellowfive@161: function Amr:HideJunkWindow() yellowfive@161: if not _frameJunk then return end yellowfive@161: _frameJunk:Hide() yellowfive@161: end yellowfive@161: yellowfive@161: function Amr:ShowJunkWindow() yellowfive@161: yellowfive@179: if InCombatLockdown() then return end yellowfive@179: yellowfive@161: if not _frameJunk then yellowfive@161: _frameJunk = AceGUI:Create("AmrUiFrame") yellowfive@161: _frameJunk:SetStatusTable(Amr.db.profile.junkWindow) -- window position is remembered in db yellowfive@161: _frameJunk:SetCallback("OnClose", onJunkFrameClose) yellowfive@161: _frameJunk:SetLayout("None") yellowfive@161: _frameJunk:SetWidth(400) yellowfive@161: _frameJunk:SetHeight(700) yellowfive@161: _frameJunk:SetBorderColor(Amr.Colors.BorderBlue) yellowfive@161: _frameJunk:SetBackgroundColor(Amr.Colors.Bg) yellowfive@161: yellowfive@161: if Amr.db.profile.options.uiScale ~= 1 then yellowfive@161: local scale = tonumber(Amr.db.profile.options.uiScale) yellowfive@161: _frameJunk:SetScale(scale) yellowfive@161: end yellowfive@161: yellowfive@161: local lbl = AceGUI:Create("AmrUiLabel") yellowfive@161: _frameJunk:AddChild(lbl) yellowfive@161: lbl:SetWidth(300) yellowfive@161: lbl:SetFont(Amr.CreateFont("Bold", 28, Amr.Colors.White)) yellowfive@161: lbl:SetText(L.JunkTitle) yellowfive@161: lbl:SetWordWrap(false) yellowfive@161: lbl:SetJustifyH("CENTER") yellowfive@161: lbl:SetPoint("TOP", _frameJunk.content, "TOP", 0, 30) yellowfive@161: lbl:SetCallback("OnMouseDown", function(widget) _frameJunk:StartMove() end) yellowfive@161: lbl:SetCallback("OnMouseUp", function(widget) _frameJunk:EndMove() end) yellowfive@161: yellowfive@161: _lblAction = AceGUI:Create("AmrUiLabel") yellowfive@161: _frameJunk:AddChild(_lblAction) yellowfive@161: _lblAction:SetWidth(380) yellowfive@161: _lblAction:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.TextTan)) yellowfive@161: _lblAction:SetText(" ") yellowfive@161: _lblAction:SetWordWrap(false) yellowfive@161: _lblAction:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -10) yellowfive@161: yellowfive@161: _btnBank = AceGUI:Create("AmrUiButton") yellowfive@161: _frameJunk:AddChild(_btnBank) yellowfive@161: _btnBank:SetText(L.JunkButtonBank) yellowfive@161: _btnBank:SetBackgroundColor(Amr.Colors.Green) yellowfive@161: _btnBank:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.White)) yellowfive@161: _btnBank:SetWidth(180) yellowfive@161: _btnBank:SetHeight(26) yellowfive@161: _btnBank:SetDisabled(true) yellowfive@161: _btnBank:SetCallback("OnClick", onBankClick) yellowfive@161: _btnBank:SetPoint("BOTTOMLEFT", _frameJunk.content, "BOTTOMLEFT") yellowfive@161: yellowfive@161: _lblBank = AceGUI:Create("AmrUiLabel") yellowfive@161: _frameJunk:AddChild(_lblBank) yellowfive@161: _lblBank:SetWidth(380) yellowfive@161: _lblBank:SetFont(Amr.CreateFont("Bold", 15, Amr.Colors.TextHeaderActive)) yellowfive@161: _lblBank:SetText(L.JunkBankText(0)) yellowfive@161: _lblBank:SetPoint("BOTTOMLEFT", _btnBank.frame, "TOPLEFT", 0, 10) yellowfive@161: yellowfive@161: local line = AceGUI:Create("AmrUiPanel") yellowfive@161: _frameJunk:AddChild(line) yellowfive@161: line:SetHeight(1) yellowfive@161: line:SetBackgroundColor(Amr.Colors.White) yellowfive@161: line:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -30) yellowfive@161: line:SetPoint("TOPRIGHT", _frameJunk.content, "TOPRIGHT", 0, -30) yellowfive@161: yellowfive@161: line = AceGUI:Create("AmrUiPanel") yellowfive@161: _frameJunk:AddChild(line) yellowfive@161: line:SetHeight(1) yellowfive@161: line:SetBackgroundColor(Amr.Colors.White) yellowfive@161: line:SetPoint("TOPLEFT", _frameJunk.content, "BOTTOMLEFT", 0, 60) yellowfive@161: line:SetPoint("TOPRIGHT", _frameJunk.content, "BOTTOMRIGHT", 0, 60) yellowfive@161: yellowfive@161: _panelContent = AceGUI:Create("AmrUiPanel") yellowfive@161: _panelContent:SetLayout("None") yellowfive@161: _panelContent:SetTransparent() yellowfive@161: _frameJunk:AddChild(_panelContent) yellowfive@161: _panelContent:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -31) yellowfive@161: _panelContent:SetPoint("BOTTOMRIGHT", _frameJunk.content, "BOTTOMRIGHT", 0, 60) yellowfive@161: yellowfive@161: yellowfive@161: Amr:RefreshJunkUi() yellowfive@161: else yellowfive@161: _frameJunk:Show() yellowfive@161: Amr:RefreshJunkUi() yellowfive@161: end yellowfive@161: yellowfive@161: _frameJunk:Raise() yellowfive@161: end yellowfive@161: yellowfive@161: local function canDisenchant() yellowfive@161: yellowfive@161: local prof1, prof2 = GetProfessions(); yellowfive@161: local profs = {} yellowfive@161: table.insert(profs, prof1) yellowfive@161: table.insert(profs, prof2) yellowfive@161: for i,prof in ipairs(profs) do yellowfive@161: if prof then yellowfive@161: local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof); yellowfive@161: if Amr.ProfessionSkillLineToName[skillLine] == "Enchanting" and skillLevel > 0 then yellowfive@161: return true yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: return false yellowfive@161: end yellowfive@161: yellowfive@161: -- yellowfive@161: -- Find a matching item that is not in the player's inventory (bank or equipped) yellowfive@161: -- yellowfive@161: local function findMatchingNonBagItem(matchItem, usedItems) yellowfive@161: yellowfive@161: local loc = ItemLocation.CreateEmpty() yellowfive@161: yellowfive@161: -- check equipped yellowfive@161: local equippedBagId = -1000 yellowfive@161: if not usedItems[equippedBagId] then yellowfive@161: usedItems[equippedBagId] = {} yellowfive@161: end yellowfive@161: yellowfive@161: for slotNum = 1, #Amr.SlotIds do yellowfive@161: local slotId = Amr.SlotIds[slotNum] yellowfive@161: if not usedItems[equippedBagId][slotId] then yellowfive@161: local itemLink = GetInventoryItemLink("player", slotId) yellowfive@161: if itemLink then yellowfive@161: local itemData = Amr.ParseItemLink(itemLink) yellowfive@161: if itemData then yellowfive@161: -- see if this is an azerite item and read azerite power ids yellowfive@161: loc:SetEquipmentSlot(slotId) yellowfive@161: if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then yellowfive@161: local powers = Amr.ReadAzeritePowers(loc) yellowfive@161: if powers then yellowfive@161: itemData.azerite = powers yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: -- see if it matches yellowfive@161: if Amr.CountItemDifferences(matchItem, itemData) == 0 then yellowfive@161: usedItems[equippedBagId][slotId] = true yellowfive@161: itemData.bagId = bagId yellowfive@161: itemData.slotId = slotId yellowfive@161: return itemData yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: -- check bank data yellowfive@163: local bestMatchDiffs = 100000 yellowfive@163: local bestMatch = nil yellowfive@163: local threshold yellowfive@163: yellowfive@161: if Amr.db.char.BankItems then yellowfive@161: for bagId, v in pairs(Amr.db.char.BankItems) do yellowfive@161: if not usedItems[bagId] then yellowfive@161: usedItems[bagId] = {} yellowfive@161: end yellowfive@161: yellowfive@161: for i, itemData in ipairs(v) do yellowfive@161: if itemData and not usedItems[bagId][i] then yellowfive@161: -- see if it matches yellowfive@163: local diffs = Amr.CountItemDifferences(matchItem, itemData) yellowfive@163: if diffs == 0 then yellowfive@161: usedItems[bagId][i] = true yellowfive@161: itemData.bagId = bagId yellowfive@161: itemData.slotId = i yellowfive@161: return itemData yellowfive@163: elseif diffs < 10000 then yellowfive@163: if itemData.azerite and #itemData.azerite > 0 then yellowfive@163: threshold = 100 yellowfive@163: else yellowfive@163: threshold = 10000 yellowfive@163: end yellowfive@163: if diffs < threshold and diffs < bestMatchDiffs then yellowfive@163: -- closest match we could find yellowfive@163: bestMatchDiffs = diffs yellowfive@163: itemData.bagId = bagId yellowfive@163: itemData.slotId = i yellowfive@163: bestMatch = itemData yellowfive@163: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@163: -- if we couldn't get a perfect match, take the best match that might have some small differences like yellowfive@163: -- an old school enchant or upgrade ID that didn't load yellowfive@163: if bestMatch then yellowfive@163: usedItems[bestMatch.bagId][bestMatch.slotId] = true yellowfive@163: return bestMatch yellowfive@163: else yellowfive@163: return nil yellowfive@163: end yellowfive@161: end yellowfive@161: yellowfive@161: local function renderItem(item, itemLink, scroll) yellowfive@161: yellowfive@161: local panel = AceGUI:Create("AmrUiPanel") yellowfive@161: scroll:AddChild(panel) yellowfive@161: panel:SetLayout("None") yellowfive@161: panel:SetTransparent() yellowfive@161: panel:SetWidth(380) yellowfive@161: panel:SetHeight(40) yellowfive@161: yellowfive@161: -- ilvl label yellowfive@161: local lblIlvl = AceGUI:Create("AmrUiLabel") yellowfive@161: panel:AddChild(lblIlvl) yellowfive@161: lblIlvl:SetPoint("LEFT", panel.content, "LEFT", 0, 0) yellowfive@161: lblIlvl:SetWidth(35) yellowfive@161: lblIlvl:SetFont(Amr.CreateFont("Italic", 13, Amr.Colors.TextTan)) yellowfive@161: yellowfive@161: -- icon yellowfive@161: local icon = AceGUI:Create("AmrUiIcon") yellowfive@161: panel:AddChild(icon) yellowfive@161: icon:SetBorderWidth(1) yellowfive@161: icon:SetIconBorderColor(Amr.Colors.White) yellowfive@161: icon:SetWidth(28) yellowfive@161: icon:SetHeight(28) yellowfive@161: icon:SetPoint("LEFT", lblIlvl.frame, "RIGHT", 0, 0) yellowfive@161: yellowfive@161: -- item name/link label yellowfive@161: local lblItem = AceGUI:Create("AmrUiTextButton") yellowfive@161: panel:AddChild(lblItem) yellowfive@161: lblItem:SetPoint("LEFT", icon.frame, "RIGHT", 0, 0) yellowfive@161: lblItem:SetWordWrap(false) yellowfive@161: lblItem:SetJustifyH("LEFT") yellowfive@161: lblItem:SetWidth(300) yellowfive@161: lblItem:SetHeight(28) yellowfive@161: lblItem:SetFont(Amr.CreateFont("Regular", 13, Amr.Colors.White)) yellowfive@161: lblItem:SetHoverBackgroundColor(Amr.Colors.Black, 0.3) yellowfive@161: lblItem:SetTextPadding(0, 0, 0, 5) yellowfive@161: lblItem:SetCallback("PreClick", onItemPreClick) yellowfive@161: lblItem:SetCallback("OnClick", onItemClick) yellowfive@161: lblItem:SetUserData("itemData", item) yellowfive@161: yellowfive@161: -- fill the name/ilvl labels, which may require asynchronous loading of item information yellowfive@161: if itemLink then yellowfive@161: local gameItem = Item:CreateFromItemLink(itemLink) yellowfive@161: if gameItem then yellowfive@161: local q = gameItem:GetItemQuality() yellowfive@161: lblItem:SetFont(Amr.CreateFont("Regular", 13, Amr.Colors.Qualities[q] or Amr.Colors.White)) yellowfive@161: lblItem:SetHoverFont(Amr.CreateFont("Regular", 13, Amr.Colors.Qualities[q] or Amr.Colors.White)) yellowfive@161: lblItem:SetText(gameItem:GetItemName()) yellowfive@161: lblIlvl:SetText(gameItem:GetCurrentItemLevel()) yellowfive@161: icon:SetIconBorderColor(Amr.Colors.Qualities[q] or Amr.Colors.White) yellowfive@161: icon:SetIcon(gameItem:GetItemIcon()) yellowfive@161: Amr:SetItemTooltip(lblItem, gameItem:GetItemLink(), "ANCHOR_BOTTOMRIGHT", 0, 30) yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: end yellowfive@161: yellowfive@161: -- yellowfive@161: -- Just updates state without re-rendering the list of junk yellowfive@161: -- yellowfive@161: function Amr:SetJunkUiState() yellowfive@161: yellowfive@161: -- don't do anything if the window is not open yellowfive@161: if not _frameJunk then return end yellowfive@161: yellowfive@161: -- cache whether the player can disenchant whenever the ui is refreshed yellowfive@161: _canDisenchant = canDisenchant() yellowfive@161: yellowfive@161: -- update action label yellowfive@161: if _isScrapOpen then yellowfive@161: _lblAction:SetText(L.JunkScrap) yellowfive@161: elseif _isMerchantOpen then yellowfive@161: _lblAction:SetText(L.JunkVendor) yellowfive@161: elseif _canDisenchant then yellowfive@161: _lblAction:SetText(L.JunkDisenchant) yellowfive@161: else yellowfive@161: _lblAction:SetText(" ") yellowfive@161: end yellowfive@161: yellowfive@161: -- update bank button state yellowfive@161: _btnBank:SetDisabled(not _isBankOpen) yellowfive@161: end yellowfive@161: yellowfive@161: -- yellowfive@161: -- Refresh the entire UI, including re-rendering the junk list yellowfive@161: -- yellowfive@161: function Amr:RefreshJunkUi() yellowfive@161: yellowfive@161: -- don't do anything if the window is not open yellowfive@161: if not _frameJunk then return end yellowfive@161: yellowfive@161: Amr:SetJunkUiState() yellowfive@161: yellowfive@161: -- clear out any previous data yellowfive@161: _panelContent:ReleaseChildren() yellowfive@161: yellowfive@161: local data = Amr.db.char.JunkData yellowfive@161: yellowfive@161: if not data or not data.Junk or #data.Junk <= 0 then yellowfive@161: local lbl = AceGUI:Create("AmrUiLabel") yellowfive@161: _panelContent:AddChild(lbl) yellowfive@161: lbl:SetFont(Amr.CreateFont("Italic", 16, Amr.Colors.TextGray)) yellowfive@161: lbl:SetText(L.JunkEmpty) yellowfive@161: lbl:SetPoint("TOPLEFT", _panelContent.content, "TOPLEFT", 0, -10) yellowfive@161: _lblBank:SetVisible(false) yellowfive@161: _btnBank:SetVisible(false) yellowfive@161: else yellowfive@161: yellowfive@161: _panelContent:SetLayout("Fill") yellowfive@161: yellowfive@161: local scroll = AceGUI:Create("AmrUiScrollFrame") yellowfive@161: scroll:SetLayout("List") yellowfive@161: _panelContent:AddChild(scroll) yellowfive@161: yellowfive@161: -- render items currently in the player's inventory yellowfive@161: local usedItems = {} yellowfive@161: local bankCount = 0 yellowfive@161: local missingCount = 0 yellowfive@161: yellowfive@161: -- if we have any "keep" items, those are exact duplicates of ones to be junked, yellowfive@161: -- be sure to "reserve" those first yellowfive@161: if data.Keep then yellowfive@161: for uniqueId, item in pairs(data.Keep) do yellowfive@161: -- check if an exact match is in the player's bank data or equipped yellowfive@161: local matchItem = findMatchingNonBagItem(item, usedItems) yellowfive@161: yellowfive@161: -- if not, find one in the player's bags yellowfive@161: if not matchItem then yellowfive@161: matchItem = findMatchingBagItem(item, usedItems) yellowfive@161: end yellowfive@161: yellowfive@161: if not matchItem then yellowfive@161: -- abort, player's data must be out of sync yellowfive@161: local lbl = AceGUI:Create("AmrUiLabel") yellowfive@161: _panelContent:AddChild(lbl) yellowfive@161: lbl:SetWidth(380) yellowfive@161: lbl:SetFont(Amr.CreateFont("Italic", 13, Amr.Colors.TextGray)) yellowfive@161: lbl:SetText(L.JunkOutOfSync) yellowfive@161: lbl:SetPoint("TOPLEFT", _panelContent.content, "TOPLEFT", 0, -10) yellowfive@161: yellowfive@161: _lblBank:SetVisible(false) yellowfive@161: _btnBank:SetVisible(false) yellowfive@161: yellowfive@161: return yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: -- now render any junk items in the player's bags, and a count of how many are elsewhere (usually bank) yellowfive@161: for i, item in ipairs(data.Junk) do yellowfive@161: local matchItem = findMatchingBagItem(item, usedItems) yellowfive@161: if matchItem then yellowfive@161: local itemLink = Amr.CreateItemLink(matchItem) yellowfive@161: renderItem(matchItem, itemLink, scroll) yellowfive@161: else yellowfive@161: -- see if it is in the bank or equipped yellowfive@161: matchItem = findMatchingNonBagItem(item, usedItems) yellowfive@161: if matchItem then yellowfive@161: bankCount = bankCount + 1 yellowfive@161: else yellowfive@161: missingCount = missingCount + 1 yellowfive@161: end yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: _lblBank:SetText(L.JunkBankText(bankCount)) yellowfive@161: _lblBank:SetVisible(bankCount > 0) yellowfive@161: _btnBank:SetVisible(bankCount > 0) yellowfive@161: end yellowfive@161: end yellowfive@161: yellowfive@161: Amr:AddEventHandler("SCRAPPING_MACHINE_SHOW", function() yellowfive@161: _isScrapOpen = true yellowfive@161: if Amr.db.profile.options.junkVendor and Amr.db.char.JunkData and Amr.db.char.JunkData.Junk and #Amr.db.char.JunkData.Junk > 0 then yellowfive@161: Amr:ShowJunkWindow() yellowfive@161: else yellowfive@161: Amr:SetJunkUiState() yellowfive@161: end yellowfive@161: end) yellowfive@161: yellowfive@161: Amr:AddEventHandler("SCRAPPING_MACHINE_CLOSE", function() yellowfive@161: _isScrapOpen = false yellowfive@161: if Amr.db.profile.options.junkVendor then yellowfive@161: Amr:HideJunkWindow() yellowfive@161: else yellowfive@161: Amr:SetJunkUiState() yellowfive@161: end yellowfive@161: end) yellowfive@161: yellowfive@161: Amr:AddEventHandler("MERCHANT_SHOW", function() yellowfive@161: _isMerchantOpen = true yellowfive@161: if Amr.db.profile.options.junkVendor and Amr.db.char.JunkData and Amr.db.char.JunkData.Junk and #Amr.db.char.JunkData.Junk > 0 then yellowfive@161: Amr:ShowJunkWindow() yellowfive@161: else yellowfive@161: Amr:SetJunkUiState() yellowfive@161: end yellowfive@161: end) yellowfive@161: yellowfive@161: Amr:AddEventHandler("MERCHANT_CLOSED", function() yellowfive@161: _isMerchantOpen = false yellowfive@161: if Amr.db.profile.options.junkVendor then yellowfive@161: Amr:HideJunkWindow() yellowfive@161: else yellowfive@161: Amr:SetJunkUiState() yellowfive@161: end yellowfive@161: end) yellowfive@161: yellowfive@161: Amr:AddEventHandler("BANKFRAME_OPENED", function() yellowfive@161: _isBankOpen = true yellowfive@161: Amr:SetJunkUiState() yellowfive@161: end) yellowfive@161: yellowfive@161: Amr:AddEventHandler("BANKFRAME_CLOSED", function() yellowfive@161: _isBankOpen = false yellowfive@161: Amr:SetJunkUiState() yellowfive@161: end)