Mercurial > wow > askmrrobot
changeset 161:35612aee8e15
Added junk list.
author | yellowfive |
---|---|
date | Mon, 06 May 2019 14:08:03 -0700 |
parents | d670336e8c89 |
children | f66108c1f674 |
files | AskMrRobot-Serializer/AskMrRobot-Serializer.lua AskMrRobot.toc Constants.lua Core.lua Gear.lua Import.lua Junk.lua Options.lua localization/enUS.lua localization/frFR.lua localization/itIT.lua localization/ptBR.lua localization/ruRU.lua ui/AmrUiTextButton.lua ui/Ui.lua |
diffstat | 15 files changed, 1092 insertions(+), 137 deletions(-) [+] |
line wrap: on
line diff
--- a/AskMrRobot-Serializer/AskMrRobot-Serializer.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/AskMrRobot-Serializer/AskMrRobot-Serializer.lua Mon May 06 14:08:03 2019 -0700 @@ -1,6 +1,6 @@ -- AskMrRobot-Serializer will serialize and communicate character data between users. -local MAJOR, MINOR = "AskMrRobot-Serializer", 75 +local MAJOR, MINOR = "AskMrRobot-Serializer", 76 local Amr, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not Amr then return end -- already loaded by something else
--- a/AskMrRobot.toc Wed Apr 24 18:00:57 2019 -0700 +++ b/AskMrRobot.toc Mon May 06 14:08:03 2019 -0700 @@ -1,7 +1,7 @@ ## Interface: 80100 ## Title: Ask Mr. Robot ## Author: Team Robot, Inc. -## Version: 75 +## Version: 76 ## Notes: Gear import/export, combat logging, and more. ## URL: www.askmrrobot.com ## SavedVariables: AskMrRobotDb4 @@ -45,6 +45,7 @@ Export.lua Import.lua +Junk.lua Shopping.lua Gear.lua CombatLog.lua
--- a/Constants.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/Constants.lua Mon May 06 14:08:03 2019 -0700 @@ -25,6 +25,8 @@ --Amr.GetItemLevel = Amr.Serializer.GetItemLevel Amr.GetItemUniqueId = Amr.Serializer.GetItemUniqueId Amr.ReadAzeritePowers = Amr.Serializer.ReadAzeritePowers +Amr.ProfessionSkillLineToName = Amr.Serializer.ProfessionSkillLineToName + -- map of slot ID to display text Amr.SlotDisplayText = { @@ -237,4 +239,4 @@ end end end) -]] \ No newline at end of file +]]
--- a/Core.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/Core.lua Mon May 06 14:08:03 2019 -0700 @@ -52,6 +52,7 @@ BagItemsAndCounts = {}, -- used mainly for the shopping list BankItemsAndCounts = {}, -- used mainly for the shopping list GearSetups = {}, -- imported gear sets + JunkData = {}, -- imported data about items that can be vendored/scrapped/disenchanted ExtraEnchantData = {}, -- enchant id to enchant display information and material information Logging = { -- character logging settings Enabled = false, -- whether logging is currently on or not @@ -66,8 +67,10 @@ }, window = {}, -- main window position settings shopWindow = {}, -- shopping list window position settings + junkWindow = {}, -- junk list window position settings options = { autoGear = false, -- auto-equip saved gear sets when changing specs + junkVendor = false, -- auto-show junk list at vendor/scrapper shopAh = false, -- auto-show shopping list at AH disableEm = false, -- disable auto-creation of equipment manager sets uiScale = 1 -- custom scale for AMR UI @@ -245,6 +248,7 @@ toggle = "Toggle", equip = "EquipGearSet", version = "PrintVersions", + junk = "ShowJunkWindow", --wipe = "Wipe", --undowipe = "UndoWipe", reset = "Reset",
--- a/Gear.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/Gear.lua Mon May 06 14:08:03 2019 -0700 @@ -537,14 +537,24 @@ _panelGear:SetPoint("BOTTOMRIGHT", container.content, "BOTTOMRIGHT") local btnShop = AceGUI:Create("AmrUiButton") + container:AddChild(btnShop) btnShop:SetText(L.GearButtonShop) btnShop:SetBackgroundColor(Amr.Colors.Blue) btnShop:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.White)) - btnShop:SetWidth(245) + btnShop:SetWidth(200) btnShop:SetHeight(26) btnShop:SetCallback("OnClick", function(widget) Amr:ShowShopWindow() end) - container:AddChild(btnShop) - btnShop:SetPoint("TOPRIGHT", container.content, "TOPRIGHT", -20, -25) + btnShop:SetPoint("TOPRIGHT", container.content, "TOPRIGHT", -42, -25) + + local btnJunk = AceGUI:Create("AmrUiButton") + container:AddChild(btnJunk) + btnJunk:SetText(L.GearButtonJunk) + btnJunk:SetBackgroundColor(Amr.Colors.Blue) + btnJunk:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.White)) + btnJunk:SetWidth(200) + btnJunk:SetHeight(26) + btnJunk:SetCallback("OnClick", function(widget) Amr:ShowJunkWindow() end) + btnJunk:SetPoint("CENTER", btnShop.frame, "CENTER", 0, 36) -- pick a default tab based on player's current spec if none is already specified if not _activeSetupId then @@ -600,7 +610,7 @@ local beginEquipGearSet, processCurrentGearOp, nextGearOp -- find the first empty slot in the player's backpack+bags -local function findFirstEmptyBagSlot() +local function findFirstEmptyBagSlot(usedBagSlots) local bagIds = {} table.insert(bagIds, BACKPACK_CONTAINER) @@ -611,9 +621,19 @@ for i, bagId in ipairs(bagIds) do local numSlots = GetContainerNumSlots(bagId) for slotId = 1, numSlots do - local _, _, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) - if not itemLink then - return bagId, slotId + if not usedBagSlots or not usedBagSlots[bagId] or not usedBagSlots[bagId][slotId] then + local _, _, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) + if not itemLink then + -- this prevents repeated calls to this from returning the same bag slot if desired + if usedBagSlots then + if not usedBagSlots[bagId] then + usedBagSlots[bagId] = {} + end + usedBagSlots[bagId][slotId] = true + end + + return bagId, slotId + end end end end @@ -621,6 +641,8 @@ return nil, nil end + + -- scan a bag for the best matching item local function scanBagForItem(item, bagId, bestItem, bestDiff, bestLink) local numSlots = GetContainerNumSlots(bagId) @@ -1262,3 +1284,8 @@ Amr:AddEventHandler("ITEM_UNLOCKED", handleItemUnlocked) end + + +-- export some local methods we need elsewhere +Amr.CountItemDifferences = countItemDifferences +Amr.FindFirstEmptyBagSlot = findFirstEmptyBagSlot
--- a/Import.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/Import.lua Mon May 06 14:08:03 2019 -0700 @@ -27,11 +27,11 @@ if _panelCover then _panelCover:SetVisible(false) end - - -- do an import if the data starts and ends with a dollar sign - local txt = _txtImport:GetText() + + -- do an import if the data starts with a dollar sign + local txt = _txtImport:GetText() local txtLen = string.len(txt) - if txtLen > 2 and string.sub(txt, 1, 1) == '$' then + if txtLen > 6 and (string.sub(txt, 1, 1) == '$' or string.sub(txt, 1, 5) == "_bib_" or string.sub(txt, 1, 6) == "_junk_") then onImportOkClick() end @@ -122,6 +122,131 @@ ---------------------------------------------------------------------------- -- +-- Helper to parse a list of items in the standard item list format. +-- +local function parseItemList(parts, startPos, endToken, hasSlot) + + local importData = {} + + local prevItemId = 0 + local prevGemId = 0 + local prevEnchantId = 0 + local prevUpgradeId = 0 + local prevBonusId = 0 + local prevLevel = 0 + local prevAzeriteId = 0 + local digits = { + ["-"] = true, + ["0"] = true, + ["1"] = true, + ["2"] = true, + ["3"] = true, + ["4"] = true, + ["5"] = true, + ["6"] = true, + ["7"] = true, + ["8"] = true, + ["9"] = true, + } + for i = startPos, #parts do + local itemString = parts[i] + if itemString == endToken then + break + elseif itemString ~= "" and itemString ~= "_" then + local tokens = {} + local bonusIds = {} + local azerite = {} + local hasBonuses = false + local hasAzerites = false + local token = "" + local prop = "i" + local tokenComplete = false + for j = 1, string.len(itemString) do + local c = string.sub(itemString, j, j) + if digits[c] == nil then + tokenComplete = true + else + token = token .. c + end + + if tokenComplete or j == string.len(itemString) then + local val = tonumber(token) + if prop == "i" then + val = val + prevItemId + prevItemId = val + elseif prop == "u" then + val = val + prevUpgradeId + prevUpgradeId = val + elseif prop == "v" then + val = val + prevLevel + prevLevel = val + elseif prop == "b" then + val = val + prevBonusId + prevBonusId = val + elseif prop == "x" or prop == "y" or prop == "z" then + val = val + prevGemId + prevGemId = val + elseif prop == "e" then + val = val + prevEnchantId + prevEnchantId = val + elseif prop == "a" then + val = val + prevAzeriteId + prevAzeriteId = val + end + + if prop == "b" then + table.insert(bonusIds, val) + hasBonuses = true + elseif prop == "a" then + table.insert(azerite, val) + hasAzerites = true + else + tokens[prop] = val + end + + token = "" + tokenComplete = false + + -- we have moved on to the next token + prop = c + end + end + + local obj = {} + + if hasSlot then + importData[tonumber(tokens["s"])] = obj + else + table.insert(importData, obj) + end + + obj.id = tokens["i"] + obj.suffixId = tokens["f"] or 0 + obj.upgradeId = tokens["u"] or 0 + obj.level = tokens["v"] or 0 + obj.enchantId = tokens["e"] or 0 + obj.inventoryId = tokens["t"] or 0 + + obj.gemIds = {} + table.insert(obj.gemIds, tokens["x"] or 0) + table.insert(obj.gemIds, tokens["y"] or 0) + table.insert(obj.gemIds, tokens["z"] or 0) + table.insert(obj.gemIds, 0) + + if hasBonuses then + obj.bonusIds = bonusIds + end + + if hasAzerites then + obj.azerite = azerite + end + end + end + + return importData +end + +-- -- Import a character, returning nil on success, otherwise an error message, import result stored in the db. -- function Amr:ImportCharacter(data, isTest, isChild) @@ -132,10 +257,16 @@ if data == nil or string.len(data) == 0 then return L.ImportErrorEmpty end - + -- if multiple setups are included in the data, parse each individually, then quit - local specParts = { strsplit("\n", data) } - if #specParts > 1 then + local specParts = { strsplit("\n", data) } + + if #specParts > 1 and specParts[1] == "_junk_" then + -- if the string starts with "_junk_" then it is the junk list + Amr:ImportJunkList(specParts[2], currentPlayerData) + return + + elseif #specParts > 1 then -- clear out any previously-imported BiB setups when importing new ones (non-BiB will always be imported one at a time) for i = #Amr.db.char.GearSetups, 1, -1 do if Amr.db.char.GearSetups[i].IsBib then @@ -213,122 +344,14 @@ -- if we make it this far, the data is valid, so read item information local specSlot = tonumber(parts[11]) - local importData = {} - local enchantInfo = {} - - local prevItemId = 0 - local prevGemId = 0 - local prevEnchantId = 0 - local prevUpgradeId = 0 - local prevBonusId = 0 - local prevLevel = 0 - local prevAzeriteId = 0 - local digits = { - ["-"] = true, - ["0"] = true, - ["1"] = true, - ["2"] = true, - ["3"] = true, - ["4"] = true, - ["5"] = true, - ["6"] = true, - ["7"] = true, - ["8"] = true, - ["9"] = true, - } - for i = 16, #parts do - local itemString = parts[i] - if itemString ~= "" and itemString ~= "_" then - local tokens = {} - local bonusIds = {} - local azerite = {} - local hasBonuses = false - local hasAzerites = false - local token = "" - local prop = "i" - local tokenComplete = false - for j = 1, string.len(itemString) do - local c = string.sub(itemString, j, j) - if digits[c] == nil then - tokenComplete = true - else - token = token .. c - end - - if tokenComplete or j == string.len(itemString) then - local val = tonumber(token) - if prop == "i" then - val = val + prevItemId - prevItemId = val - elseif prop == "u" then - val = val + prevUpgradeId - prevUpgradeId = val - elseif prop == "v" then - val = val + prevLevel - prevLevel = val - elseif prop == "b" then - val = val + prevBonusId - prevBonusId = val - elseif prop == "x" or prop == "y" or prop == "z" then - val = val + prevGemId - prevGemId = val - elseif prop == "e" then - val = val + prevEnchantId - prevEnchantId = val - elseif prop == "a" then - val = val + prevAzeriteId - prevAzeriteId = val - end - - if prop == "b" then - table.insert(bonusIds, val) - hasBonuses = true - elseif prop == "a" then - table.insert(azerite, val) - hasAzerites = true - else - tokens[prop] = val - end - - token = "" - tokenComplete = false - - -- we have moved on to the next token - prop = c - end - end - - local obj = {} - importData[tonumber(tokens["s"])] = obj - - obj.id = tokens["i"] - obj.suffixId = tokens["f"] or 0 - obj.upgradeId = tokens["u"] or 0 - obj.level = tokens["v"] or 0 - obj.enchantId = tokens["e"] or 0 - obj.inventoryId = tokens["t"] or 0 - - obj.gemIds = {} - table.insert(obj.gemIds, tokens["x"] or 0) - table.insert(obj.gemIds, tokens["y"] or 0) - table.insert(obj.gemIds, tokens["z"] or 0) - table.insert(obj.gemIds, 0) - - if hasBonuses then - obj.bonusIds = bonusIds - end - - if hasAzerites then - obj.azerite = azerite - end - end - end + local importData = parseItemList(parts, 16, "n/a", true) -- extra information contains setup id, display label, then extra enchant info parts = { strsplit("@", data1[3]) } local setupId = parts[2] local setupName = parts[3] + local enchantInfo = {} for i = 4, #parts do local infoParts = { strsplit("\\", parts[i]) } @@ -410,3 +433,95 @@ Amr:UpdateShoppingData(currentPlayerData) end end + +-- +-- Import a list of items that are junk. +-- +function Amr:ImportJunkList(data, currentPlayerData) + + local data1 = { strsplit("$", data) } + if #data1 ~= 3 then + return L.ImportErrorFormat + end + + local parts = { strsplit(";", data1[2]) } + + -- require a minimum version + local ver = tonumber(parts[1]) + if ver < Amr.MIN_IMPORT_VERSION then + return L.ImportErrorVersion + end + + -- require name match + local region = parts[2] + local realm = parts[3] + local name = parts[4] + if name ~= currentPlayerData.Name then + local importPlayerName = name .. " (" .. realm .. ")" + local you = currentPlayerData.Name .. " (" .. currentPlayerData.Realm .. ")" + return L.ImportErrorChar(importPlayerName, you) + end + + local keepStartPos = 0 + local junkStartPos = 0 + for i = 5, #parts do + local partString = parts[i] + if partString == ".k" then + keepStartPos = i + 1 + elseif partString == ".d" then + junkStartPos = i + 1 + end + end + + Amr.db.char.JunkData = {} + + -- Keep is a lookup by unique id + local keep = parseItemList(parts, keepStartPos, ".d", false) + Amr.db.char.JunkData.Keep = {} + for i = 1, #keep do + local uniqueId = Amr.GetItemUniqueId(keep[i]) + Amr.db.char.JunkData.Keep[uniqueId] = keep[i] + end + + -- Junk is a simple list of items to discard, in the desired display order + Amr.db.char.JunkData.Junk = parseItemList(parts, junkStartPos, "n/a", false) + + -- extra information contains extra enchant info + if #data1 >= 3 then + parts = { strsplit("@", data1[3]) } + + local enchantInfo = {} + + for i = 2, #parts do + local infoParts = { strsplit("\\", parts[i]) } + + if infoParts[1] == "e" then + + local enchObj = {} + enchObj.id = tonumber(infoParts[2]) + enchObj.itemId = tonumber(infoParts[3]) + enchObj.spellId = tonumber(infoParts[4]) + enchObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.StatsShort[s] end) + + local mats = infoParts[6] + if string.len(mats) > 0 then + enchObj.materials = {} + mats = { strsplit(",", mats) } + for j = 1, #mats do + local kv = { strsplit("=", mats[j]) } + enchObj.materials[tonumber(kv[1])] = tonumber(kv[2]) + end + end + + enchantInfo[enchObj.id] = enchObj + end + end + + for k,v in pairs(enchantInfo) do + Amr.db.char.ExtraEnchantData[k] = v + end + end + + -- show the junk window after a successful junk import + Amr:ShowJunkWindow() +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Junk.lua Mon May 06 14:08:03 2019 -0700 @@ -0,0 +1,656 @@ +local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") +local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) +local AceGUI = LibStub("AceGUI-3.0") + +local _frameJunk +local _lblAction +local _lblBank +local _btnBank +local _panelContent + +local _canDisenchant = false +local _isScrapOpen = false +local _isMerchantOpen = false +local _isBankOpen = false + +-- +-- Scan a bag for the specified item, returning the first exact match found +-- +local function scanBag(bagId, matchItem, usedItems) + + local numSlots = GetContainerNumSlots(bagId) + local loc = ItemLocation.CreateEmpty() + + if not usedItems[bagId] then + usedItems[bagId] = {} + end + + for slotId = 1, numSlots do + if not usedItems[bagId][slotId] then + local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) + if itemLink ~= nil then + local itemData = Amr.Serializer.ParseItemLink(itemLink) + if itemData ~= nil then + -- see if this is an azerite item and read azerite power ids + loc:SetBagAndSlot(bagId, slotId) + if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then + local powers = Amr.ReadAzeritePowers(loc) + if powers then + itemData.azerite = powers + end + end + + -- see if it matches + if Amr.CountItemDifferences(matchItem, itemData) == 0 then + usedItems[bagId][slotId] = true + itemData.bagId = bagId + itemData.slotId = slotId + return itemData + end + end + end + end + end + + return nil +end + +-- +-- Find a matching item in the player's bags +-- +local function findMatchingBagItem(item, usedItems) + + local matchItem = scanBag(BACKPACK_CONTAINER, item, usedItems) -- backpack + if not matchItem then + for bagId = 1, NUM_BAG_SLOTS do + matchItem = scanBag(bagId, item, usedItems) + if matchItem then break end + end + end + + return matchItem +end + + +-- +-- item actions +-- +local _deSpellName = GetSpellInfo(13262); +local _deMacro = "/stopmacro [combat][btn:2]\n/stopcasting\n/cast %s\n/use %s %s"; + +local function onItemPreClick(widget) + + local item = widget:GetUserData("itemData") + + if item and _canDisenchant and (not _isScrapOpen and not _isMerchantOpen) then + -- only way i can find to disenchant and item on click is to call a macro, gross but works + local matchItem = findMatchingBagItem(item, {}) + if matchItem then + widget:SetMacroText(_deMacro:format(_deSpellName, matchItem.bagId, matchItem.slotId)) + else + widget:SetMacroText(nil) + Amr:Print(L.JunkItemNotFound) + end + else + widget:SetMacroText(nil) + end +end + +local function onItemClick(widget) + + local item = widget:GetUserData("itemData") + if not item then return end + + local action = nil + if _isScrapOpen then + action = "scrap" + elseif _isMerchantOpen then + action = "sell" + elseif _canDisenchant then + action = "disenchant" + end + + if not action then return end + + local matchItem = findMatchingBagItem(item, {}) + if matchItem then + if action == "scrap" then + UseContainerItem(matchItem.bagId, matchItem.slotId) + elseif action == "sell" then + UseContainerItem(matchItem.bagId, matchItem.slotId) + end + + -- note for disenchant, the macro has handled the action, this will simply remove the item from the list + + -- re-render the list with this item removed; + -- AceGUI doesn't give a good way to remove a ui element from a container and re-render, + -- so we sort of hack it and modify the collection of children directly, + -- avoids the expensive logic of finding and matching all the items when the list changes as a user sells stuff + local scroll = widget.parent.parent + local newChildren = {} + for i = 1, #scroll.children do + local child = scroll.children[i] + if child ~= widget.parent then + table.insert(newChildren, child) + end + end + scroll.children = newChildren + + -- dispose the item just removed, then re-render the list + widget.parent:Release() + widget.parent.parent:DoLayout() + else + Amr:Print(L.JunkItemNotFound) + end +end + + +-- +-- bank withdraw stuff +-- +local _bankUsedBagSlots = nil +local finishBankWithdraw +local doBankWithdraw + +finishBankWithdraw = function() + + local done = true + + if _isBankOpen and _bankUsedBagSlots then + for bagId,v in pairs(_bankUsedBagSlots) do + for slotId,v in pairs(v) do + local _, _, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) + if not itemLink then + done = false + break + end + end + if not done then break end + end + end + + if not done then + -- wait a second and try again + Amr.Wait(1, function() + doBankWithdraw() + end) + else + + print("bank withdraw done") + + -- reset state + _bankUsedBagSlots = nil + _btnBank:SetDisabled(not _isBankOpen) + + -- re-render the junk list + Amr:RefreshJunkUi() + end +end + +doBankWithdraw = function() + if not _isBankOpen then return end + + local data = Amr.db.char.JunkData + if not data.Junk then return end + + print("doing bank withdraw...") + + -- disable button while processing + _btnBank:SetDisabled(true) + + local bagList = {} + table.insert(bagList, BANK_CONTAINER) + for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do + table.insert(bagList, bagId) + end + + local usedItems = {} + _bankUsedBagSlots = {} + + for i,item in ipairs(data.Junk) do + -- stop immediately if the bank is closed + if not _isBankOpen then + finishBankWithdraw() + return + end + + -- check if already in bags + local matchItem = findMatchingBagItem(item, usedItems) + if not matchItem then + -- find it in the bank + for j = 1, #bagList do + matchItem = scanBag(bagList[j], item, usedItems) + if matchItem then break end + end + else + matchItem = nil + end + + if matchItem then + -- move it to the player's bags if there is space + local bagId, slotId = Amr.FindFirstEmptyBagSlot(_bankUsedBagSlots) + if bagId then + UseContainerItem(matchItem.bagId, matchItem.slotId) + else + -- no more empty bag slots + break + end + end + end + + -- wait a second and see if all the moves actually finished + Amr.Wait(1, function() + finishBankWithdraw() + end) +end + +local function onBankClick() + if not _frameJunk or not _isBankOpen then return end + + doBankWithdraw() +end + + +local function onJunkFrameClose(widget) + AceGUI:Release(widget) + _frameJunk = nil + _lblAction = nil + _lblBank = nil + _btnBank = nil + _panelContent = nil +end + +function Amr:HideJunkWindow() + if not _frameJunk then return end + _frameJunk:Hide() +end + +function Amr:ShowJunkWindow() + + if not _frameJunk then + _frameJunk = AceGUI:Create("AmrUiFrame") + _frameJunk:SetStatusTable(Amr.db.profile.junkWindow) -- window position is remembered in db + _frameJunk:SetCallback("OnClose", onJunkFrameClose) + _frameJunk:SetLayout("None") + _frameJunk:SetWidth(400) + _frameJunk:SetHeight(700) + _frameJunk:SetBorderColor(Amr.Colors.BorderBlue) + _frameJunk:SetBackgroundColor(Amr.Colors.Bg) + + if Amr.db.profile.options.uiScale ~= 1 then + local scale = tonumber(Amr.db.profile.options.uiScale) + _frameJunk:SetScale(scale) + end + + local lbl = AceGUI:Create("AmrUiLabel") + _frameJunk:AddChild(lbl) + lbl:SetWidth(300) + lbl:SetFont(Amr.CreateFont("Bold", 28, Amr.Colors.White)) + lbl:SetText(L.JunkTitle) + lbl:SetWordWrap(false) + lbl:SetJustifyH("CENTER") + lbl:SetPoint("TOP", _frameJunk.content, "TOP", 0, 30) + lbl:SetCallback("OnMouseDown", function(widget) _frameJunk:StartMove() end) + lbl:SetCallback("OnMouseUp", function(widget) _frameJunk:EndMove() end) + + _lblAction = AceGUI:Create("AmrUiLabel") + _frameJunk:AddChild(_lblAction) + _lblAction:SetWidth(380) + _lblAction:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.TextTan)) + _lblAction:SetText(" ") + _lblAction:SetWordWrap(false) + _lblAction:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -10) + + _btnBank = AceGUI:Create("AmrUiButton") + _frameJunk:AddChild(_btnBank) + _btnBank:SetText(L.JunkButtonBank) + _btnBank:SetBackgroundColor(Amr.Colors.Green) + _btnBank:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.White)) + _btnBank:SetWidth(180) + _btnBank:SetHeight(26) + _btnBank:SetDisabled(true) + _btnBank:SetCallback("OnClick", onBankClick) + _btnBank:SetPoint("BOTTOMLEFT", _frameJunk.content, "BOTTOMLEFT") + + _lblBank = AceGUI:Create("AmrUiLabel") + _frameJunk:AddChild(_lblBank) + _lblBank:SetWidth(380) + _lblBank:SetFont(Amr.CreateFont("Bold", 15, Amr.Colors.TextHeaderActive)) + _lblBank:SetText(L.JunkBankText(0)) + _lblBank:SetPoint("BOTTOMLEFT", _btnBank.frame, "TOPLEFT", 0, 10) + + local line = AceGUI:Create("AmrUiPanel") + _frameJunk:AddChild(line) + line:SetHeight(1) + line:SetBackgroundColor(Amr.Colors.White) + line:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -30) + line:SetPoint("TOPRIGHT", _frameJunk.content, "TOPRIGHT", 0, -30) + + line = AceGUI:Create("AmrUiPanel") + _frameJunk:AddChild(line) + line:SetHeight(1) + line:SetBackgroundColor(Amr.Colors.White) + line:SetPoint("TOPLEFT", _frameJunk.content, "BOTTOMLEFT", 0, 60) + line:SetPoint("TOPRIGHT", _frameJunk.content, "BOTTOMRIGHT", 0, 60) + + _panelContent = AceGUI:Create("AmrUiPanel") + _panelContent:SetLayout("None") + _panelContent:SetTransparent() + _frameJunk:AddChild(_panelContent) + _panelContent:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -31) + _panelContent:SetPoint("BOTTOMRIGHT", _frameJunk.content, "BOTTOMRIGHT", 0, 60) + + + Amr:RefreshJunkUi() + else + _frameJunk:Show() + Amr:RefreshJunkUi() + end + + _frameJunk:Raise() +end + +local function canDisenchant() + + local prof1, prof2 = GetProfessions(); + local profs = {} + table.insert(profs, prof1) + table.insert(profs, prof2) + for i,prof in ipairs(profs) do + if prof then + local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof); + if Amr.ProfessionSkillLineToName[skillLine] == "Enchanting" and skillLevel > 0 then + return true + end + end + end + + return false +end + +-- +-- Find a matching item that is not in the player's inventory (bank or equipped) +-- +local function findMatchingNonBagItem(matchItem, usedItems) + + local loc = ItemLocation.CreateEmpty() + + -- check equipped + local equippedBagId = -1000 + if not usedItems[equippedBagId] then + usedItems[equippedBagId] = {} + end + + for slotNum = 1, #Amr.SlotIds do + local slotId = Amr.SlotIds[slotNum] + if not usedItems[equippedBagId][slotId] then + local itemLink = GetInventoryItemLink("player", slotId) + if itemLink then + local itemData = Amr.ParseItemLink(itemLink) + if itemData then + -- see if this is an azerite item and read azerite power ids + loc:SetEquipmentSlot(slotId) + if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then + local powers = Amr.ReadAzeritePowers(loc) + if powers then + itemData.azerite = powers + end + end + + -- see if it matches + if Amr.CountItemDifferences(matchItem, itemData) == 0 then + usedItems[equippedBagId][slotId] = true + itemData.bagId = bagId + itemData.slotId = slotId + return itemData + end + end + end + end + end + + -- check bank data + if Amr.db.char.BankItems then + for bagId, v in pairs(Amr.db.char.BankItems) do + if not usedItems[bagId] then + usedItems[bagId] = {} + end + + for i, itemData in ipairs(v) do + if itemData and not usedItems[bagId][i] then + -- see if it matches + if Amr.CountItemDifferences(matchItem, itemData) == 0 then + usedItems[bagId][i] = true + itemData.bagId = bagId + itemData.slotId = i + return itemData + end + end + end + end + end + + return nil +end + +local function renderItem(item, itemLink, scroll) + + local panel = AceGUI:Create("AmrUiPanel") + scroll:AddChild(panel) + panel:SetLayout("None") + panel:SetTransparent() + panel:SetWidth(380) + panel:SetHeight(40) + + -- ilvl label + local lblIlvl = AceGUI:Create("AmrUiLabel") + panel:AddChild(lblIlvl) + lblIlvl:SetPoint("LEFT", panel.content, "LEFT", 0, 0) + lblIlvl:SetWidth(35) + lblIlvl:SetFont(Amr.CreateFont("Italic", 13, Amr.Colors.TextTan)) + + -- icon + local icon = AceGUI:Create("AmrUiIcon") + panel:AddChild(icon) + icon:SetBorderWidth(1) + icon:SetIconBorderColor(Amr.Colors.White) + icon:SetWidth(28) + icon:SetHeight(28) + icon:SetPoint("LEFT", lblIlvl.frame, "RIGHT", 0, 0) + + -- item name/link label + local lblItem = AceGUI:Create("AmrUiTextButton") + panel:AddChild(lblItem) + lblItem:SetPoint("LEFT", icon.frame, "RIGHT", 0, 0) + lblItem:SetWordWrap(false) + lblItem:SetJustifyH("LEFT") + lblItem:SetWidth(300) + lblItem:SetHeight(28) + lblItem:SetFont(Amr.CreateFont("Regular", 13, Amr.Colors.White)) + lblItem:SetHoverBackgroundColor(Amr.Colors.Black, 0.3) + lblItem:SetTextPadding(0, 0, 0, 5) + lblItem:SetCallback("PreClick", onItemPreClick) + lblItem:SetCallback("OnClick", onItemClick) + lblItem:SetUserData("itemData", item) + + -- fill the name/ilvl labels, which may require asynchronous loading of item information + if itemLink then + local gameItem = Item:CreateFromItemLink(itemLink) + if gameItem then + local q = gameItem:GetItemQuality() + lblItem:SetFont(Amr.CreateFont("Regular", 13, Amr.Colors.Qualities[q] or Amr.Colors.White)) + lblItem:SetHoverFont(Amr.CreateFont("Regular", 13, Amr.Colors.Qualities[q] or Amr.Colors.White)) + lblItem:SetText(gameItem:GetItemName()) + lblIlvl:SetText(gameItem:GetCurrentItemLevel()) + icon:SetIconBorderColor(Amr.Colors.Qualities[q] or Amr.Colors.White) + icon:SetIcon(gameItem:GetItemIcon()) + Amr:SetItemTooltip(lblItem, gameItem:GetItemLink(), "ANCHOR_BOTTOMRIGHT", 0, 30) + end + end + +end + +-- +-- Just updates state without re-rendering the list of junk +-- +function Amr:SetJunkUiState() + + -- don't do anything if the window is not open + if not _frameJunk then return end + + -- cache whether the player can disenchant whenever the ui is refreshed + _canDisenchant = canDisenchant() + + -- update action label + if _isScrapOpen then + _lblAction:SetText(L.JunkScrap) + elseif _isMerchantOpen then + _lblAction:SetText(L.JunkVendor) + elseif _canDisenchant then + _lblAction:SetText(L.JunkDisenchant) + else + _lblAction:SetText(" ") + end + + -- update bank button state + _btnBank:SetDisabled(not _isBankOpen) +end + +-- +-- Refresh the entire UI, including re-rendering the junk list +-- +function Amr:RefreshJunkUi() + + -- don't do anything if the window is not open + if not _frameJunk then return end + + Amr:SetJunkUiState() + + -- clear out any previous data + _panelContent:ReleaseChildren() + + local data = Amr.db.char.JunkData + + if not data or not data.Junk or #data.Junk <= 0 then + local lbl = AceGUI:Create("AmrUiLabel") + _panelContent:AddChild(lbl) + lbl:SetFont(Amr.CreateFont("Italic", 16, Amr.Colors.TextGray)) + lbl:SetText(L.JunkEmpty) + lbl:SetPoint("TOPLEFT", _panelContent.content, "TOPLEFT", 0, -10) + _lblBank:SetVisible(false) + _btnBank:SetVisible(false) + else + + _panelContent:SetLayout("Fill") + + local scroll = AceGUI:Create("AmrUiScrollFrame") + scroll:SetLayout("List") + _panelContent:AddChild(scroll) + + -- render items currently in the player's inventory + local usedItems = {} + local bankCount = 0 + local missingCount = 0 + + -- if we have any "keep" items, those are exact duplicates of ones to be junked, + -- be sure to "reserve" those first + if data.Keep then + for uniqueId, item in pairs(data.Keep) do + -- check if an exact match is in the player's bank data or equipped + local matchItem = findMatchingNonBagItem(item, usedItems) + + -- if not, find one in the player's bags + if not matchItem then + matchItem = findMatchingBagItem(item, usedItems) + end + + if not matchItem then + -- abort, player's data must be out of sync + local lbl = AceGUI:Create("AmrUiLabel") + _panelContent:AddChild(lbl) + lbl:SetWidth(380) + lbl:SetFont(Amr.CreateFont("Italic", 13, Amr.Colors.TextGray)) + lbl:SetText(L.JunkOutOfSync) + lbl:SetPoint("TOPLEFT", _panelContent.content, "TOPLEFT", 0, -10) + + _lblBank:SetVisible(false) + _btnBank:SetVisible(false) + + return + end + end + end + + -- now render any junk items in the player's bags, and a count of how many are elsewhere (usually bank) + for i, item in ipairs(data.Junk) do + local matchItem = findMatchingBagItem(item, usedItems) + if matchItem then + local itemLink = Amr.CreateItemLink(matchItem) + renderItem(matchItem, itemLink, scroll) + else + -- see if it is in the bank or equipped + matchItem = findMatchingNonBagItem(item, usedItems) + if matchItem then + bankCount = bankCount + 1 + else + missingCount = missingCount + 1 + end + end + end + + _lblBank:SetText(L.JunkBankText(bankCount)) + _lblBank:SetVisible(bankCount > 0) + _btnBank:SetVisible(bankCount > 0) + + -- in most cases, this is because the user has sold/scrapped the items already + --if missingCount > 0 then + -- Amr:Print(L.JunkMissingText(missingCount)) + --end + end +end + +Amr:AddEventHandler("SCRAPPING_MACHINE_SHOW", function() + _isScrapOpen = true + 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 + Amr:ShowJunkWindow() + else + Amr:SetJunkUiState() + end +end) + +Amr:AddEventHandler("SCRAPPING_MACHINE_CLOSE", function() + _isScrapOpen = false + if Amr.db.profile.options.junkVendor then + Amr:HideJunkWindow() + else + Amr:SetJunkUiState() + end +end) + +Amr:AddEventHandler("MERCHANT_SHOW", function() + _isMerchantOpen = true + 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 + Amr:ShowJunkWindow() + else + Amr:SetJunkUiState() + end +end) + +Amr:AddEventHandler("MERCHANT_CLOSED", function() + _isMerchantOpen = false + if Amr.db.profile.options.junkVendor then + Amr:HideJunkWindow() + else + Amr:SetJunkUiState() + end +end) + +Amr:AddEventHandler("BANKFRAME_OPENED", function() + _isBankOpen = true + Amr:SetJunkUiState() +end) + +Amr:AddEventHandler("BANKFRAME_CLOSED", function() + _isBankOpen = false + Amr:SetJunkUiState() +end)
--- a/Options.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/Options.lua Mon May 06 14:08:03 2019 -0700 @@ -4,6 +4,7 @@ local _chkMinimap local _chkAutoGear +local _chkJunk local _chkAh local _chkEm local _txtScale @@ -106,14 +107,17 @@ _chkAutoGear, desc2 = createCheck(container, "autoGear", L.OptionsAutoGearName, L.OptionsAutoGearDesc) _chkAutoGear:SetPoint("TOPLEFT", desc.frame, "BOTTOMLEFT", -24, -20) - _chkAh, desc = createCheck(container, "shopAh", L.OptionsShopAhName, L.OptionsShopAhDesc) - _chkAh:SetPoint("TOPLEFT", desc2.frame, "BOTTOMLEFT", -24, -20) + _chkJunk, desc = createCheck(container, "junkVendor", L.OptionsJunkVendorName, L.OptionsJunkVendorDesc) + _chkJunk:SetPoint("TOPLEFT", desc2.frame, "BOTTOMLEFT", -24, -20) + + _chkAh, desc2 = createCheck(container, "shopAh", L.OptionsShopAhName, L.OptionsShopAhDesc) + _chkAh:SetPoint("TOPLEFT", desc.frame, "BOTTOMLEFT", -24, -20) - _chkEm, desc2 = createCheck(container, "disableEm", L.OptionsDisableEmName, L.OptionsDisableEmDesc) - _chkEm:SetPoint("TOPLEFT", desc.frame, "BOTTOMLEFT", -24, -20) + _chkEm, desc = createCheck(container, "disableEm", L.OptionsDisableEmName, L.OptionsDisableEmDesc) + _chkEm:SetPoint("TOPLEFT", desc2.frame, "BOTTOMLEFT", -24, -20) - _txtScale, desc = createSmallTextbox(container, "uiScale", L.OptionsUiScaleName, L.OptionsUiScaleDesc) - _txtScale:SetPoint("TOPLEFT", desc2.frame, "BOTTOMLEFT", -43, -20) + _txtScale, desc2 = createSmallTextbox(container, "uiScale", L.OptionsUiScaleName, L.OptionsUiScaleDesc) + _txtScale:SetPoint("TOPLEFT", desc.frame, "BOTTOMLEFT", -43, -20) -- initialize state of controls Amr:RefreshOptionsUi() @@ -122,6 +126,7 @@ function Amr:ReleaseTabOptions() _chkMinimap = nil _chkAutoGear = nil + _chkJunk = nil _chkAh = nil _chkEm = nil _txtScale = nil @@ -136,7 +141,11 @@ if _chkAutoGear then _chkAutoGear:SetChecked(self.db.profile.options.autoGear) end - + + if _chkJunk then + _chkJunk:SetChecked(self.db.profile.options.junkVendor) + end + if _chkAh then _chkAh:SetChecked(self.db.profile.options.shopAh) end
--- a/localization/enUS.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/localization/enUS.lua Mon May 06 14:08:03 2019 -0700 @@ -177,6 +177,7 @@ L.GearButtonEquip = function(spec) return string.format("Activate %s Spec and Equip Gear", spec) end +L.GearButtonJunk = "Show Junk List" L.GearButtonShop = "Show Shopping List" L.GearEquipErrorCombat = "Cannot change spec/gear while in combat!" @@ -226,6 +227,25 @@ --[[---------------------------------------------------------------------- +Junk List +------------------------------------------------------------------------]] +L.JunkTitle = "Junk List" +L.JunkEmpty = "You have no junk items" +L.JunkScrap = "Click an item to add to the scrapper" +L.JunkVendor = "Click an item to sell" +L.JunkDisenchant = "Click an item to disenchant" +L.JunkBankText = function(count) + return count .. " junk items are not in your bags" +end +L.JunkMissingText = function(count) + return "Warning! " .. count .. " junk items could not be found" +end +L.JunkButtonBank = "Retrieve from Bank" +L.JunkOutOfSync = "An item in your junk list could not be found. Try opening your bank for a few seconds, then export to the website, then import again." +L.JunkItemNotFound = "That item could not be found in your bags. Try closing and opening the Junk List to refresh it." + + +--[[---------------------------------------------------------------------- Shopping List ------------------------------------------------------------------------]] L.ShopTitle = "Shopping List" @@ -296,6 +316,9 @@ L.OptionsAutoGearName = "Automatically equip gear on spec change" L.OptionsAutoGearDesc = "Whenever you change spec (via the in-game UI, another addon, etc.), your imported AMR gear sets (on the Gear tab) will be automatically equipped." +L.OptionsJunkVendorName = "Automatically show junk list at vendors and scrapper" +L.OptionsJunkVendorDesc = "Whenever you open the scrapper or a vendor, automatically show the junk list window if your list is not empty." + L.OptionsShopAhName = "Automatically show shopping list at auction house" L.OptionsShopAhDesc = "Whenever you open the auction house, automatically show the shopping list window. You can click on items in the shopping list to quickly search for them in the auction house."
--- a/localization/frFR.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/localization/frFR.lua Mon May 06 14:08:03 2019 -0700 @@ -162,6 +162,7 @@ L.GearButtonEquip = function(spec) return string.format("Activer la spé %s et équipper le stuff", spec) end +L.GearButtonJunk = "Voir Junk List" L.GearButtonShop = "Voir Shopping List" L.GearEquipErrorCombat = "Impossible de changer de spé/stuff pendant un combat !" @@ -211,6 +212,25 @@ --[[---------------------------------------------------------------------- +Junk List +------------------------------------------------------------------------]] +L.JunkTitle = "Junk List" +L.JunkEmpty = "You have no junk items" +L.JunkScrap = "Click an item to add to the scrapper" +L.JunkVendor = "Click an item to sell" +L.JunkDisenchant = "Click an item to disenchant" +L.JunkBankText = function(count) + return count .. " junk items are not in your bags" +end +L.JunkMissingText = function(count) + return "Warning! " .. count .. " junk items could not be found" +end +L.JunkButtonBank = "Retrieve from Bank" +L.JunkOutOfSync = "An item in your junk list could not be found. Try opening your bank for a few seconds, then export to the website, then import again." +L.JunkItemNotFound = "That item could not be found in your bags. Try closing and opening the Junk List to refresh it." + + +--[[---------------------------------------------------------------------- Shopping List ------------------------------------------------------------------------]] L.ShopTitle = "Shopping List" @@ -281,6 +301,9 @@ L.OptionsAutoGearName = "Equippe le stuff automatiquement lors d'un changement de spé" L.OptionsAutoGearDesc = "Quand tu changes de spé (via l'interface utilisateur, un autre add-on, etc.) le stuff importé depuis AMR (onglet Gear) pour cette spé est automatiquement équippé." +L.OptionsJunkVendorName = "Automatically show junk list at vendors and scrapper" +L.OptionsJunkVendorDesc = "Whenever you open the scrapper or a vendor, automatically show the junk list window if your list is not empty." + L.OptionsShopAhName = "Voir la shopping list automatiquement à l'hôtel des ventes" L.OptionsShopAhDesc = "Quand tu ouvres l'hôtel des ventes, la fenêtre de la shopping list s'ouvre automatiquement. Tu peux cliquer sur un item dans la shopping list pour le chercher automatiquement dans l'hôtel des ventes."
--- a/localization/itIT.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/localization/itIT.lua Mon May 06 14:08:03 2019 -0700 @@ -162,6 +162,7 @@ L.GearButtonEquip = function(spec) return string.format("Attiva %s Spec ed Equip", spec) end +L.GearButtonJunk = "Show Junk List" L.GearButtonShop = "Show Shopping List" L.GearEquipErrorCombat = "Non puoi cambiare spec/eqiup mentre sei in combattimento!" @@ -211,6 +212,25 @@ --[[---------------------------------------------------------------------- +Junk List +------------------------------------------------------------------------]] +L.JunkTitle = "Junk List" +L.JunkEmpty = "You have no junk items" +L.JunkScrap = "Click an item to add to the scrapper" +L.JunkVendor = "Click an item to sell" +L.JunkDisenchant = "Click an item to disenchant" +L.JunkBankText = function(count) + return count .. " junk items are not in your bags" +end +L.JunkMissingText = function(count) + return "Warning! " .. count .. " junk items could not be found" +end +L.JunkButtonBank = "Retrieve from Bank" +L.JunkOutOfSync = "An item in your junk list could not be found. Try opening your bank for a few seconds, then export to the website, then import again." +L.JunkItemNotFound = "That item could not be found in your bags. Try closing and opening the Junk List to refresh it." + + +--[[---------------------------------------------------------------------- Shopping List ------------------------------------------------------------------------]] L.ShopTitle = "Lista della spesa" @@ -281,6 +301,9 @@ L.OptionsAutoGearName = "Equipaggia automaticamente al cambio spec" L.OptionsAutoGearDesc = "Ogni volta che cambi spec (tramite l'interfaccia di gioco, addon o AMR.), i tuoi set importati su AMR saranno equipaggiati automaticamente." +L.OptionsJunkVendorName = "Automatically show junk list at vendors and scrapper" +L.OptionsJunkVendorDesc = "Whenever you open the scrapper or a vendor, automatically show the junk list window if your list is not empty." + L.OptionsShopAhName = "Mostra automaticamente la lista della spesa quando sei all'asta" L.OptionsShopAhDesc = "Ogni volta che apri l'asta, mostra automaticamente la lista della spesa. Puoi cliccare sugli oggetti nella lista della spesa per cercarli velocemente all'asta."
--- a/localization/ptBR.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/localization/ptBR.lua Mon May 06 14:08:03 2019 -0700 @@ -163,6 +163,7 @@ L.GearButtonEquip = function(spec) return string.format("Ativar Spec %s e Usar Equipamento", spec) end +L.GearButtonJunk = "Mostrar Lista de Junk" L.GearButtonShop = "Mostrar Lista de Compras" L.GearEquipErrorCombat = "Impossível trocar spec/equipamento em combate!" @@ -212,6 +213,25 @@ --[[---------------------------------------------------------------------- +Junk List +------------------------------------------------------------------------]] +L.JunkTitle = "Junk List" +L.JunkEmpty = "You have no junk items" +L.JunkScrap = "Click an item to add to the scrapper" +L.JunkVendor = "Click an item to sell" +L.JunkDisenchant = "Click an item to disenchant" +L.JunkBankText = function(count) + return count .. " junk items are not in your bags" +end +L.JunkMissingText = function(count) + return "Warning! " .. count .. " junk items could not be found" +end +L.JunkButtonBank = "Retrieve from Bank" +L.JunkOutOfSync = "An item in your junk list could not be found. Try opening your bank for a few seconds, then export to the website, then import again." +L.JunkItemNotFound = "That item could not be found in your bags. Try closing and opening the Junk List to refresh it." + + +--[[---------------------------------------------------------------------- Shopping List ------------------------------------------------------------------------]] L.ShopTitle = "Lista de Compras" @@ -282,6 +302,9 @@ L.OptionsAutoGearName = "Trocar equipamento automaticamente ao trocar de spec" L.OptionsAutoGearDesc = "Sempre que trocar a spec (via UI no jogo, outro addon, etc.), suas listas de equipamentos importadas (na guia Equipamento) serão equipadas automaticamente." +L.OptionsJunkVendorName = "Automatically show junk list at vendors and scrapper" +L.OptionsJunkVendorDesc = "Whenever you open the scrapper or a vendor, automatically show the junk list window if your list is not empty." + L.OptionsShopAhName = "Mostrar automaticamente a lista de compras na casa de leilões" L.OptionsShopAhDesc = "Sempre que você abrir a casa de leilões, automaticamente será mostrada a janela da lista de compras. Você pode clicar nos itens da lista de compras para procurar rapidamente por eles na casa de leilões."
--- a/localization/ruRU.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/localization/ruRU.lua Mon May 06 14:08:03 2019 -0700 @@ -165,6 +165,7 @@ L.GearButtonEquip = function(spec) return string.format("Активировать %s спек и одеть экипировку", spec) end +L.GearButtonJunk = "Show Junk List" L.GearButtonShop = "Показать список покупок" L.GearEquipErrorCombat = "Вы не можете сменить спек/экипировку в бою!" @@ -214,6 +215,25 @@ --[[---------------------------------------------------------------------- +Junk List +------------------------------------------------------------------------]] +L.JunkTitle = "Junk List" +L.JunkEmpty = "You have no junk items" +L.JunkScrap = "Click an item to add to the scrapper" +L.JunkVendor = "Click an item to sell" +L.JunkDisenchant = "Click an item to disenchant" +L.JunkBankText = function(count) + return count .. " junk items are not in your bags" +end +L.JunkMissingText = function(count) + return "Warning! " .. count .. " junk items could not be found" +end +L.JunkButtonBank = "Retrieve from Bank" +L.JunkOutOfSync = "An item in your junk list could not be found. Try opening your bank for a few seconds, then export to the website, then import again." +L.JunkItemNotFound = "That item could not be found in your bags. Try closing and opening the Junk List to refresh it." + + +--[[---------------------------------------------------------------------- Shopping List ------------------------------------------------------------------------]] L.ShopTitle = "Список покупок" @@ -284,6 +304,9 @@ L.OptionsAutoGearName = "Автоматически одевать экипировку при смене спека" L.OptionsAutoGearDesc = "Если вы смените спек (посредством игрового меню, другого аддона, и т.д.), Ваши загруженные наборы (вкладка Экипировка) будут автоматически экипированы." +L.OptionsJunkVendorName = "Automatically show junk list at vendors and scrapper" +L.OptionsJunkVendorDesc = "Whenever you open the scrapper or a vendor, automatically show the junk list window if your list is not empty." + L.OptionsShopAhName = "Автоматически показывать список покупок при открытии аукциона" L.OptionsShopAhDesc = "При открытии окна аукциона, автоматически показывать список покупок. Вы можете кликнуть по предмету в списке покупок для быстрого поиска на аукционе."
--- a/ui/AmrUiTextButton.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/ui/AmrUiTextButton.lua Mon May 06 14:08:03 2019 -0700 @@ -19,10 +19,19 @@ --[[----------------------------------------------------------------------------- Scripts -------------------------------------------------------------------------------]] -local function buttonOnClick(frame, ...) +-- to facilitate some use cases, we have click fired on PostClick for this widget +--[[local function buttonOnClick(frame, ...) AceGUI:ClearFocus() --PlaySound("igMainMenuOption") frame.obj:Fire("OnClick", ...) +end]] + +local function buttonPreClick(frame, ...) + frame.obj:Fire("PreClick", ...) +end + +local function buttonPostClick(frame, ...) + frame.obj:Fire("OnClick", ...) end local function buttonOnEnter(frame) @@ -181,6 +190,19 @@ else self.frame:Hide() end + end, + + -- + -- If text is specified, turns this into a button that calls a macro + -- + ["SetMacroText"] = function(self, text) + if text then + self.frame:SetAttribute("type", "macro") + self.frame:SetAttribute("macrotext", text) + else + self.frame:SetAttribute("type", nil) + self.frame:SetAttribute("macrotext", nil) + end end } @@ -189,7 +211,7 @@ -------------------------------------------------------------------------------]] local function Constructor() local name = "AmrUiTextButton" .. AceGUI:GetNextWidgetNum(Type) - local frame = CreateFrame("Button", name, UIParent) + local frame = CreateFrame("Button", name, UIParent, "SecureActionButtonTemplate") frame:Hide() local txt = frame:CreateFontString() @@ -201,7 +223,9 @@ frame:EnableMouse(true) frame:SetScript("OnEnter", buttonOnEnter) frame:SetScript("OnLeave", buttonOnLeave) - frame:SetScript("OnClick", buttonOnClick) + --frame:SetScript("OnClick", buttonOnClick) + frame:SetScript("PreClick", buttonPreClick) + frame:SetScript("PostClick", buttonPostClick) local bg = frame:CreateTexture() bg:SetAllPoints()
--- a/ui/Ui.lua Wed Apr 24 18:00:57 2019 -0700 +++ b/ui/Ui.lua Mon May 06 14:08:03 2019 -0700 @@ -123,6 +123,7 @@ end end) + local _mainFrame = nil local _mainTabs = nil local _mainCover = nil @@ -370,6 +371,7 @@ Amr.db.profile.window = {} Amr.db.profile.lootWindow = {} Amr.db.profile.shopWindow = {} + Amr.db.profile.junkWindow = {} end -- show the UI if not shown already, and select the specified tab