annotate Junk.lua @ 200:6e8838b231d4 v97

Fixed issue with distinguishing different variants of the same item.
author Yellowfive
date Wed, 13 Jan 2021 13:11:54 -0600
parents 4aeedce4c995
children
rev   line source
yellowfive@161 1 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot")
yellowfive@161 2 local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true)
yellowfive@161 3 local AceGUI = LibStub("AceGUI-3.0")
yellowfive@161 4
yellowfive@161 5 local _frameJunk
yellowfive@161 6 local _lblAction
yellowfive@161 7 local _lblBank
yellowfive@161 8 local _btnBank
yellowfive@161 9 local _panelContent
yellowfive@161 10
yellowfive@161 11 local _canDisenchant = false
yellowfive@161 12 local _isScrapOpen = false
yellowfive@161 13 local _isMerchantOpen = false
yellowfive@161 14 local _isBankOpen = false
yellowfive@161 15
yellowfive@161 16 --
yellowfive@161 17 -- Scan a bag for the specified item, returning the first exact match found
yellowfive@161 18 --
yellowfive@161 19 local function scanBag(bagId, matchItem, usedItems)
yellowfive@161 20
yellowfive@161 21 local numSlots = GetContainerNumSlots(bagId)
yellowfive@161 22 local loc = ItemLocation.CreateEmpty()
yellowfive@161 23
yellowfive@161 24 if not usedItems[bagId] then
yellowfive@161 25 usedItems[bagId] = {}
yellowfive@161 26 end
yellowfive@161 27
yellowfive@163 28 local bestMatchDiffs = 1000000
yellowfive@163 29 local bestMatch = nil
yellowfive@163 30 local threshold
yellowfive@163 31
yellowfive@161 32 for slotId = 1, numSlots do
yellowfive@161 33 if not usedItems[bagId][slotId] then
yellowfive@161 34 local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId)
yellowfive@161 35 if itemLink ~= nil then
yellowfive@161 36 local itemData = Amr.Serializer.ParseItemLink(itemLink)
yellowfive@161 37 if itemData ~= nil then
yellowfive@161 38 -- see if this is an azerite item and read azerite power ids
yellowfive@185 39 --[[loc:SetBagAndSlot(bagId, slotId)
yellowfive@161 40 if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then
yellowfive@161 41 local powers = Amr.ReadAzeritePowers(loc)
yellowfive@161 42 if powers then
yellowfive@161 43 itemData.azerite = powers
yellowfive@161 44 end
yellowfive@185 45 end]]
yellowfive@161 46
yellowfive@161 47 -- see if it matches
yellowfive@163 48 local diffs = Amr.CountItemDifferences(matchItem, itemData)
yellowfive@163 49 if diffs == 0 then
yellowfive@161 50 usedItems[bagId][slotId] = true
yellowfive@161 51 itemData.bagId = bagId
yellowfive@161 52 itemData.slotId = slotId
yellowfive@161 53 return itemData
yellowfive@191 54 elseif diffs < 100000 then
yellowfive@163 55 if itemData.azerite and #itemData.azerite > 0 then
yellowfive@191 56 threshold = 1000
yellowfive@163 57 else
yellowfive@191 58 threshold = 100000
yellowfive@163 59 end
yellowfive@163 60 if diffs < threshold and diffs < bestMatchDiffs then
yellowfive@163 61 -- closest match we could find
yellowfive@163 62 bestMatchDiffs = diffs
yellowfive@163 63 itemData.bagId = bagId
yellowfive@163 64 itemData.slotId = slotId
yellowfive@163 65 bestMatch = itemData
yellowfive@163 66 end
yellowfive@161 67 end
yellowfive@161 68 end
yellowfive@161 69 end
yellowfive@161 70 end
yellowfive@161 71 end
yellowfive@163 72
yellowfive@163 73 -- if we couldn't get a perfect match, take the best match that might have some small differences like
yellowfive@163 74 -- an old school enchant or upgrade ID that didn't load
yellowfive@163 75 if bestMatch then
yellowfive@163 76 usedItems[bestMatch.bagId][bestMatch.slotId] = true
yellowfive@163 77 return bestMatch
yellowfive@163 78 else
yellowfive@163 79 return nil
yellowfive@163 80 end
yellowfive@161 81 end
yellowfive@161 82
yellowfive@161 83 --
yellowfive@161 84 -- Find a matching item in the player's bags
yellowfive@161 85 --
yellowfive@161 86 local function findMatchingBagItem(item, usedItems)
yellowfive@161 87
yellowfive@161 88 local matchItem = scanBag(BACKPACK_CONTAINER, item, usedItems) -- backpack
yellowfive@161 89 if not matchItem then
yellowfive@161 90 for bagId = 1, NUM_BAG_SLOTS do
yellowfive@161 91 matchItem = scanBag(bagId, item, usedItems)
yellowfive@161 92 if matchItem then break end
yellowfive@161 93 end
yellowfive@161 94 end
yellowfive@161 95
yellowfive@161 96 return matchItem
yellowfive@161 97 end
yellowfive@161 98
yellowfive@161 99
yellowfive@161 100 --
yellowfive@161 101 -- item actions
yellowfive@161 102 --
yellowfive@161 103 local _deSpellName = GetSpellInfo(13262);
yellowfive@161 104 local _deMacro = "/stopmacro [combat][btn:2]\n/stopcasting\n/cast %s\n/use %s %s";
yellowfive@161 105
yellowfive@161 106 local function onItemPreClick(widget)
yellowfive@161 107
yellowfive@161 108 local item = widget:GetUserData("itemData")
yellowfive@161 109
yellowfive@161 110 if item and _canDisenchant and (not _isScrapOpen and not _isMerchantOpen) then
yellowfive@161 111 -- only way i can find to disenchant and item on click is to call a macro, gross but works
yellowfive@161 112 local matchItem = findMatchingBagItem(item, {})
yellowfive@161 113 if matchItem then
yellowfive@161 114 widget:SetMacroText(_deMacro:format(_deSpellName, matchItem.bagId, matchItem.slotId))
yellowfive@161 115 else
yellowfive@161 116 widget:SetMacroText(nil)
yellowfive@161 117 Amr:Print(L.JunkItemNotFound)
yellowfive@161 118 end
yellowfive@161 119 else
yellowfive@161 120 widget:SetMacroText(nil)
yellowfive@161 121 end
yellowfive@161 122 end
yellowfive@161 123
yellowfive@161 124 local function onItemClick(widget)
yellowfive@161 125
yellowfive@161 126 local item = widget:GetUserData("itemData")
yellowfive@161 127 if not item then return end
yellowfive@161 128
yellowfive@161 129 local action = nil
yellowfive@161 130 if _isScrapOpen then
yellowfive@161 131 action = "scrap"
yellowfive@161 132 elseif _isMerchantOpen then
yellowfive@161 133 action = "sell"
yellowfive@161 134 elseif _canDisenchant then
yellowfive@161 135 action = "disenchant"
yellowfive@161 136 end
yellowfive@161 137
yellowfive@161 138 if not action then return end
yellowfive@161 139
yellowfive@161 140 local matchItem = findMatchingBagItem(item, {})
yellowfive@161 141 if matchItem then
yellowfive@161 142 if action == "scrap" then
yellowfive@161 143 UseContainerItem(matchItem.bagId, matchItem.slotId)
yellowfive@161 144 elseif action == "sell" then
yellowfive@161 145 UseContainerItem(matchItem.bagId, matchItem.slotId)
yellowfive@161 146 end
yellowfive@161 147
yellowfive@161 148 -- note for disenchant, the macro has handled the action, this will simply remove the item from the list
yellowfive@161 149
yellowfive@161 150 -- re-render the list with this item removed;
yellowfive@161 151 -- AceGUI doesn't give a good way to remove a ui element from a container and re-render,
yellowfive@161 152 -- so we sort of hack it and modify the collection of children directly,
yellowfive@161 153 -- avoids the expensive logic of finding and matching all the items when the list changes as a user sells stuff
yellowfive@161 154 local scroll = widget.parent.parent
yellowfive@161 155 local newChildren = {}
yellowfive@161 156 for i = 1, #scroll.children do
yellowfive@161 157 local child = scroll.children[i]
yellowfive@161 158 if child ~= widget.parent then
yellowfive@161 159 table.insert(newChildren, child)
yellowfive@161 160 end
yellowfive@161 161 end
yellowfive@161 162 scroll.children = newChildren
yellowfive@161 163
yellowfive@161 164 -- dispose the item just removed, then re-render the list
yellowfive@161 165 widget.parent:Release()
yellowfive@161 166 widget.parent.parent:DoLayout()
yellowfive@161 167 else
yellowfive@161 168 Amr:Print(L.JunkItemNotFound)
yellowfive@161 169 end
yellowfive@161 170 end
yellowfive@161 171
yellowfive@161 172
yellowfive@161 173 --
yellowfive@161 174 -- bank withdraw stuff
yellowfive@161 175 --
yellowfive@161 176 local _bankUsedBagSlots = nil
yellowfive@161 177 local finishBankWithdraw
yellowfive@161 178 local doBankWithdraw
yellowfive@161 179
yellowfive@161 180 finishBankWithdraw = function()
yellowfive@161 181
yellowfive@161 182 local done = true
yellowfive@161 183
yellowfive@161 184 if _isBankOpen and _bankUsedBagSlots then
yellowfive@161 185 for bagId,v in pairs(_bankUsedBagSlots) do
yellowfive@161 186 for slotId,v in pairs(v) do
yellowfive@161 187 local _, _, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId)
yellowfive@161 188 if not itemLink then
yellowfive@161 189 done = false
yellowfive@161 190 break
yellowfive@161 191 end
yellowfive@161 192 end
yellowfive@161 193 if not done then break end
yellowfive@161 194 end
yellowfive@161 195 end
yellowfive@161 196
yellowfive@161 197 if not done then
yellowfive@161 198 -- wait a second and try again
yellowfive@161 199 Amr.Wait(1, function()
yellowfive@161 200 doBankWithdraw()
yellowfive@161 201 end)
yellowfive@161 202 else
yellowfive@161 203
yellowfive@161 204 -- reset state
yellowfive@161 205 _bankUsedBagSlots = nil
yellowfive@161 206 _btnBank:SetDisabled(not _isBankOpen)
yellowfive@161 207
yellowfive@161 208 -- re-render the junk list
yellowfive@161 209 Amr:RefreshJunkUi()
yellowfive@161 210 end
yellowfive@161 211 end
yellowfive@161 212
yellowfive@161 213 doBankWithdraw = function()
yellowfive@161 214 if not _isBankOpen then return end
yellowfive@161 215
yellowfive@161 216 local data = Amr.db.char.JunkData
yellowfive@161 217 if not data.Junk then return end
yellowfive@161 218
yellowfive@161 219 -- disable button while processing
yellowfive@161 220 _btnBank:SetDisabled(true)
yellowfive@161 221
yellowfive@161 222 local bagList = {}
yellowfive@161 223 table.insert(bagList, BANK_CONTAINER)
yellowfive@161 224 for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do
yellowfive@161 225 table.insert(bagList, bagId)
yellowfive@161 226 end
yellowfive@161 227
yellowfive@161 228 local usedItems = {}
yellowfive@161 229 _bankUsedBagSlots = {}
yellowfive@161 230
yellowfive@161 231 for i,item in ipairs(data.Junk) do
yellowfive@161 232 -- stop immediately if the bank is closed
yellowfive@161 233 if not _isBankOpen then
yellowfive@161 234 finishBankWithdraw()
yellowfive@161 235 return
yellowfive@161 236 end
yellowfive@161 237
yellowfive@161 238 -- check if already in bags
yellowfive@161 239 local matchItem = findMatchingBagItem(item, usedItems)
yellowfive@161 240 if not matchItem then
yellowfive@161 241 -- find it in the bank
yellowfive@161 242 for j = 1, #bagList do
yellowfive@161 243 matchItem = scanBag(bagList[j], item, usedItems)
yellowfive@161 244 if matchItem then break end
yellowfive@161 245 end
yellowfive@161 246 else
yellowfive@161 247 matchItem = nil
yellowfive@161 248 end
yellowfive@161 249
yellowfive@161 250 if matchItem then
yellowfive@161 251 -- move it to the player's bags if there is space
yellowfive@161 252 local bagId, slotId = Amr.FindFirstEmptyBagSlot(_bankUsedBagSlots)
yellowfive@161 253 if bagId then
yellowfive@161 254 UseContainerItem(matchItem.bagId, matchItem.slotId)
yellowfive@161 255 else
yellowfive@161 256 -- no more empty bag slots
yellowfive@161 257 break
yellowfive@161 258 end
yellowfive@161 259 end
yellowfive@161 260 end
yellowfive@161 261
yellowfive@161 262 -- wait a second and see if all the moves actually finished
yellowfive@161 263 Amr.Wait(1, function()
yellowfive@161 264 finishBankWithdraw()
yellowfive@161 265 end)
yellowfive@161 266 end
yellowfive@161 267
yellowfive@161 268 local function onBankClick()
yellowfive@161 269 if not _frameJunk or not _isBankOpen then return end
yellowfive@161 270
yellowfive@161 271 doBankWithdraw()
yellowfive@161 272 end
yellowfive@161 273
yellowfive@161 274
yellowfive@161 275 local function onJunkFrameClose(widget)
yellowfive@161 276 AceGUI:Release(widget)
yellowfive@161 277 _frameJunk = nil
yellowfive@161 278 _lblAction = nil
yellowfive@161 279 _lblBank = nil
yellowfive@161 280 _btnBank = nil
yellowfive@161 281 _panelContent = nil
yellowfive@161 282 end
yellowfive@161 283
yellowfive@161 284 function Amr:HideJunkWindow()
yellowfive@161 285 if not _frameJunk then return end
yellowfive@161 286 _frameJunk:Hide()
yellowfive@161 287 end
yellowfive@161 288
yellowfive@161 289 function Amr:ShowJunkWindow()
yellowfive@161 290
yellowfive@179 291 if InCombatLockdown() then return end
yellowfive@179 292
yellowfive@161 293 if not _frameJunk then
yellowfive@161 294 _frameJunk = AceGUI:Create("AmrUiFrame")
yellowfive@161 295 _frameJunk:SetStatusTable(Amr.db.profile.junkWindow) -- window position is remembered in db
yellowfive@161 296 _frameJunk:SetCallback("OnClose", onJunkFrameClose)
yellowfive@161 297 _frameJunk:SetLayout("None")
yellowfive@161 298 _frameJunk:SetWidth(400)
yellowfive@161 299 _frameJunk:SetHeight(700)
yellowfive@161 300 _frameJunk:SetBorderColor(Amr.Colors.BorderBlue)
yellowfive@161 301 _frameJunk:SetBackgroundColor(Amr.Colors.Bg)
yellowfive@161 302
yellowfive@161 303 if Amr.db.profile.options.uiScale ~= 1 then
yellowfive@161 304 local scale = tonumber(Amr.db.profile.options.uiScale)
yellowfive@161 305 _frameJunk:SetScale(scale)
yellowfive@161 306 end
yellowfive@161 307
yellowfive@161 308 local lbl = AceGUI:Create("AmrUiLabel")
yellowfive@161 309 _frameJunk:AddChild(lbl)
yellowfive@161 310 lbl:SetWidth(300)
yellowfive@161 311 lbl:SetFont(Amr.CreateFont("Bold", 28, Amr.Colors.White))
yellowfive@161 312 lbl:SetText(L.JunkTitle)
yellowfive@161 313 lbl:SetWordWrap(false)
yellowfive@161 314 lbl:SetJustifyH("CENTER")
yellowfive@161 315 lbl:SetPoint("TOP", _frameJunk.content, "TOP", 0, 30)
yellowfive@161 316 lbl:SetCallback("OnMouseDown", function(widget) _frameJunk:StartMove() end)
yellowfive@161 317 lbl:SetCallback("OnMouseUp", function(widget) _frameJunk:EndMove() end)
yellowfive@161 318
yellowfive@161 319 _lblAction = AceGUI:Create("AmrUiLabel")
yellowfive@161 320 _frameJunk:AddChild(_lblAction)
yellowfive@161 321 _lblAction:SetWidth(380)
yellowfive@161 322 _lblAction:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.TextTan))
yellowfive@161 323 _lblAction:SetText(" ")
yellowfive@161 324 _lblAction:SetWordWrap(false)
yellowfive@161 325 _lblAction:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -10)
yellowfive@161 326
yellowfive@161 327 _btnBank = AceGUI:Create("AmrUiButton")
yellowfive@161 328 _frameJunk:AddChild(_btnBank)
yellowfive@161 329 _btnBank:SetText(L.JunkButtonBank)
yellowfive@161 330 _btnBank:SetBackgroundColor(Amr.Colors.Green)
yellowfive@161 331 _btnBank:SetFont(Amr.CreateFont("Bold", 14, Amr.Colors.White))
yellowfive@161 332 _btnBank:SetWidth(180)
yellowfive@161 333 _btnBank:SetHeight(26)
yellowfive@161 334 _btnBank:SetDisabled(true)
yellowfive@161 335 _btnBank:SetCallback("OnClick", onBankClick)
yellowfive@161 336 _btnBank:SetPoint("BOTTOMLEFT", _frameJunk.content, "BOTTOMLEFT")
yellowfive@161 337
yellowfive@161 338 _lblBank = AceGUI:Create("AmrUiLabel")
yellowfive@161 339 _frameJunk:AddChild(_lblBank)
yellowfive@161 340 _lblBank:SetWidth(380)
yellowfive@161 341 _lblBank:SetFont(Amr.CreateFont("Bold", 15, Amr.Colors.TextHeaderActive))
yellowfive@161 342 _lblBank:SetText(L.JunkBankText(0))
yellowfive@161 343 _lblBank:SetPoint("BOTTOMLEFT", _btnBank.frame, "TOPLEFT", 0, 10)
yellowfive@161 344
yellowfive@161 345 local line = AceGUI:Create("AmrUiPanel")
yellowfive@161 346 _frameJunk:AddChild(line)
yellowfive@161 347 line:SetHeight(1)
yellowfive@161 348 line:SetBackgroundColor(Amr.Colors.White)
yellowfive@161 349 line:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -30)
yellowfive@161 350 line:SetPoint("TOPRIGHT", _frameJunk.content, "TOPRIGHT", 0, -30)
yellowfive@161 351
yellowfive@161 352 line = AceGUI:Create("AmrUiPanel")
yellowfive@161 353 _frameJunk:AddChild(line)
yellowfive@161 354 line:SetHeight(1)
yellowfive@161 355 line:SetBackgroundColor(Amr.Colors.White)
yellowfive@161 356 line:SetPoint("TOPLEFT", _frameJunk.content, "BOTTOMLEFT", 0, 60)
yellowfive@161 357 line:SetPoint("TOPRIGHT", _frameJunk.content, "BOTTOMRIGHT", 0, 60)
yellowfive@161 358
yellowfive@161 359 _panelContent = AceGUI:Create("AmrUiPanel")
yellowfive@161 360 _panelContent:SetLayout("None")
yellowfive@161 361 _panelContent:SetTransparent()
yellowfive@161 362 _frameJunk:AddChild(_panelContent)
yellowfive@161 363 _panelContent:SetPoint("TOPLEFT", _frameJunk.content, "TOPLEFT", 0, -31)
yellowfive@161 364 _panelContent:SetPoint("BOTTOMRIGHT", _frameJunk.content, "BOTTOMRIGHT", 0, 60)
yellowfive@161 365
yellowfive@161 366
yellowfive@161 367 Amr:RefreshJunkUi()
yellowfive@161 368 else
yellowfive@161 369 _frameJunk:Show()
yellowfive@161 370 Amr:RefreshJunkUi()
yellowfive@161 371 end
yellowfive@161 372
yellowfive@161 373 _frameJunk:Raise()
yellowfive@161 374 end
yellowfive@161 375
yellowfive@161 376 local function canDisenchant()
yellowfive@161 377
yellowfive@161 378 local prof1, prof2 = GetProfessions();
yellowfive@161 379 local profs = {}
yellowfive@161 380 table.insert(profs, prof1)
yellowfive@161 381 table.insert(profs, prof2)
yellowfive@161 382 for i,prof in ipairs(profs) do
yellowfive@161 383 if prof then
yellowfive@161 384 local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof);
yellowfive@161 385 if Amr.ProfessionSkillLineToName[skillLine] == "Enchanting" and skillLevel > 0 then
yellowfive@161 386 return true
yellowfive@161 387 end
yellowfive@161 388 end
yellowfive@161 389 end
yellowfive@161 390
yellowfive@161 391 return false
yellowfive@161 392 end
yellowfive@161 393
yellowfive@161 394 --
yellowfive@161 395 -- Find a matching item that is not in the player's inventory (bank or equipped)
yellowfive@161 396 --
yellowfive@161 397 local function findMatchingNonBagItem(matchItem, usedItems)
yellowfive@161 398
yellowfive@161 399 local loc = ItemLocation.CreateEmpty()
yellowfive@161 400
yellowfive@161 401 -- check equipped
yellowfive@161 402 local equippedBagId = -1000
yellowfive@161 403 if not usedItems[equippedBagId] then
yellowfive@161 404 usedItems[equippedBagId] = {}
yellowfive@161 405 end
yellowfive@161 406
yellowfive@161 407 for slotNum = 1, #Amr.SlotIds do
yellowfive@161 408 local slotId = Amr.SlotIds[slotNum]
yellowfive@161 409 if not usedItems[equippedBagId][slotId] then
yellowfive@161 410 local itemLink = GetInventoryItemLink("player", slotId)
yellowfive@161 411 if itemLink then
yellowfive@161 412 local itemData = Amr.ParseItemLink(itemLink)
yellowfive@161 413 if itemData then
yellowfive@187 414
yellowfive@187 415 --[[
yellowfive@161 416 -- see if this is an azerite item and read azerite power ids
yellowfive@161 417 loc:SetEquipmentSlot(slotId)
yellowfive@161 418 if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem(loc) then
yellowfive@161 419 local powers = Amr.ReadAzeritePowers(loc)
yellowfive@161 420 if powers then
yellowfive@161 421 itemData.azerite = powers
yellowfive@161 422 end
yellowfive@187 423 end]]
yellowfive@161 424
yellowfive@161 425 -- see if it matches
yellowfive@161 426 if Amr.CountItemDifferences(matchItem, itemData) == 0 then
yellowfive@161 427 usedItems[equippedBagId][slotId] = true
yellowfive@161 428 itemData.bagId = bagId
yellowfive@161 429 itemData.slotId = slotId
yellowfive@161 430 return itemData
yellowfive@161 431 end
yellowfive@161 432 end
yellowfive@161 433 end
yellowfive@161 434 end
yellowfive@161 435 end
yellowfive@161 436
yellowfive@161 437 -- check bank data
yellowfive@163 438 local bestMatchDiffs = 100000
yellowfive@163 439 local bestMatch = nil
yellowfive@163 440 local threshold
yellowfive@163 441
yellowfive@161 442 if Amr.db.char.BankItems then
yellowfive@161 443 for bagId, v in pairs(Amr.db.char.BankItems) do
yellowfive@161 444 if not usedItems[bagId] then
yellowfive@161 445 usedItems[bagId] = {}
yellowfive@161 446 end
yellowfive@161 447
yellowfive@161 448 for i, itemData in ipairs(v) do
yellowfive@161 449 if itemData and not usedItems[bagId][i] then
yellowfive@161 450 -- see if it matches
yellowfive@163 451 local diffs = Amr.CountItemDifferences(matchItem, itemData)
yellowfive@163 452 if diffs == 0 then
yellowfive@161 453 usedItems[bagId][i] = true
yellowfive@161 454 itemData.bagId = bagId
yellowfive@161 455 itemData.slotId = i
yellowfive@161 456 return itemData
yellowfive@191 457 elseif diffs < 100000 then
yellowfive@163 458 if itemData.azerite and #itemData.azerite > 0 then
yellowfive@191 459 threshold = 1000
yellowfive@163 460 else
yellowfive@191 461 threshold = 100000
yellowfive@163 462 end
yellowfive@163 463 if diffs < threshold and diffs < bestMatchDiffs then
yellowfive@163 464 -- closest match we could find
yellowfive@163 465 bestMatchDiffs = diffs
yellowfive@163 466 itemData.bagId = bagId
yellowfive@163 467 itemData.slotId = i
yellowfive@163 468 bestMatch = itemData
yellowfive@163 469 end
yellowfive@161 470 end
yellowfive@161 471 end
yellowfive@161 472 end
yellowfive@161 473 end
yellowfive@161 474 end
yellowfive@161 475
yellowfive@163 476 -- if we couldn't get a perfect match, take the best match that might have some small differences like
yellowfive@163 477 -- an old school enchant or upgrade ID that didn't load
yellowfive@163 478 if bestMatch then
yellowfive@163 479 usedItems[bestMatch.bagId][bestMatch.slotId] = true
yellowfive@163 480 return bestMatch
yellowfive@163 481 else
yellowfive@163 482 return nil
yellowfive@163 483 end
yellowfive@161 484 end
yellowfive@161 485
yellowfive@161 486 local function renderItem(item, itemLink, scroll)
yellowfive@161 487
yellowfive@161 488 local panel = AceGUI:Create("AmrUiPanel")
yellowfive@161 489 scroll:AddChild(panel)
yellowfive@161 490 panel:SetLayout("None")
yellowfive@161 491 panel:SetTransparent()
yellowfive@161 492 panel:SetWidth(380)
yellowfive@161 493 panel:SetHeight(40)
yellowfive@161 494
yellowfive@161 495 -- ilvl label
yellowfive@161 496 local lblIlvl = AceGUI:Create("AmrUiLabel")
yellowfive@161 497 panel:AddChild(lblIlvl)
yellowfive@161 498 lblIlvl:SetPoint("LEFT", panel.content, "LEFT", 0, 0)
yellowfive@161 499 lblIlvl:SetWidth(35)
yellowfive@161 500 lblIlvl:SetFont(Amr.CreateFont("Italic", 13, Amr.Colors.TextTan))
yellowfive@161 501
yellowfive@161 502 -- icon
yellowfive@161 503 local icon = AceGUI:Create("AmrUiIcon")
yellowfive@161 504 panel:AddChild(icon)
yellowfive@161 505 icon:SetBorderWidth(1)
yellowfive@161 506 icon:SetIconBorderColor(Amr.Colors.White)
yellowfive@161 507 icon:SetWidth(28)
yellowfive@161 508 icon:SetHeight(28)
yellowfive@161 509 icon:SetPoint("LEFT", lblIlvl.frame, "RIGHT", 0, 0)
yellowfive@161 510
yellowfive@161 511 -- item name/link label
yellowfive@161 512 local lblItem = AceGUI:Create("AmrUiTextButton")
yellowfive@161 513 panel:AddChild(lblItem)
yellowfive@161 514 lblItem:SetPoint("LEFT", icon.frame, "RIGHT", 0, 0)
yellowfive@161 515 lblItem:SetWordWrap(false)
yellowfive@161 516 lblItem:SetJustifyH("LEFT")
yellowfive@161 517 lblItem:SetWidth(300)
yellowfive@161 518 lblItem:SetHeight(28)
yellowfive@161 519 lblItem:SetFont(Amr.CreateFont("Regular", 13, Amr.Colors.White))
yellowfive@161 520 lblItem:SetHoverBackgroundColor(Amr.Colors.Black, 0.3)
yellowfive@161 521 lblItem:SetTextPadding(0, 0, 0, 5)
yellowfive@161 522 lblItem:SetCallback("PreClick", onItemPreClick)
yellowfive@161 523 lblItem:SetCallback("OnClick", onItemClick)
yellowfive@161 524 lblItem:SetUserData("itemData", item)
yellowfive@161 525
yellowfive@161 526 -- fill the name/ilvl labels, which may require asynchronous loading of item information
yellowfive@161 527 if itemLink then
yellowfive@161 528 local gameItem = Item:CreateFromItemLink(itemLink)
yellowfive@161 529 if gameItem then
yellowfive@161 530 local q = gameItem:GetItemQuality()
yellowfive@161 531 lblItem:SetFont(Amr.CreateFont("Regular", 13, Amr.Colors.Qualities[q] or Amr.Colors.White))
yellowfive@161 532 lblItem:SetHoverFont(Amr.CreateFont("Regular", 13, Amr.Colors.Qualities[q] or Amr.Colors.White))
yellowfive@161 533 lblItem:SetText(gameItem:GetItemName())
yellowfive@161 534 lblIlvl:SetText(gameItem:GetCurrentItemLevel())
yellowfive@161 535 icon:SetIconBorderColor(Amr.Colors.Qualities[q] or Amr.Colors.White)
yellowfive@161 536 icon:SetIcon(gameItem:GetItemIcon())
yellowfive@161 537 Amr:SetItemTooltip(lblItem, gameItem:GetItemLink(), "ANCHOR_BOTTOMRIGHT", 0, 30)
yellowfive@161 538 end
yellowfive@161 539 end
yellowfive@161 540
yellowfive@161 541 end
yellowfive@161 542
yellowfive@161 543 --
yellowfive@161 544 -- Just updates state without re-rendering the list of junk
yellowfive@161 545 --
yellowfive@161 546 function Amr:SetJunkUiState()
yellowfive@161 547
yellowfive@161 548 -- don't do anything if the window is not open
yellowfive@161 549 if not _frameJunk then return end
yellowfive@161 550
yellowfive@161 551 -- cache whether the player can disenchant whenever the ui is refreshed
yellowfive@161 552 _canDisenchant = canDisenchant()
yellowfive@161 553
yellowfive@161 554 -- update action label
yellowfive@161 555 if _isScrapOpen then
yellowfive@161 556 _lblAction:SetText(L.JunkScrap)
yellowfive@161 557 elseif _isMerchantOpen then
yellowfive@161 558 _lblAction:SetText(L.JunkVendor)
yellowfive@161 559 elseif _canDisenchant then
yellowfive@161 560 _lblAction:SetText(L.JunkDisenchant)
yellowfive@161 561 else
yellowfive@161 562 _lblAction:SetText(" ")
yellowfive@161 563 end
yellowfive@161 564
yellowfive@161 565 -- update bank button state
yellowfive@161 566 _btnBank:SetDisabled(not _isBankOpen)
yellowfive@161 567 end
yellowfive@161 568
yellowfive@161 569 --
yellowfive@161 570 -- Refresh the entire UI, including re-rendering the junk list
yellowfive@161 571 --
yellowfive@161 572 function Amr:RefreshJunkUi()
yellowfive@161 573
yellowfive@161 574 -- don't do anything if the window is not open
yellowfive@161 575 if not _frameJunk then return end
yellowfive@161 576
yellowfive@161 577 Amr:SetJunkUiState()
yellowfive@161 578
yellowfive@161 579 -- clear out any previous data
yellowfive@161 580 _panelContent:ReleaseChildren()
yellowfive@161 581
yellowfive@161 582 local data = Amr.db.char.JunkData
yellowfive@161 583
yellowfive@161 584 if not data or not data.Junk or #data.Junk <= 0 then
yellowfive@161 585 local lbl = AceGUI:Create("AmrUiLabel")
yellowfive@161 586 _panelContent:AddChild(lbl)
yellowfive@161 587 lbl:SetFont(Amr.CreateFont("Italic", 16, Amr.Colors.TextGray))
yellowfive@161 588 lbl:SetText(L.JunkEmpty)
yellowfive@161 589 lbl:SetPoint("TOPLEFT", _panelContent.content, "TOPLEFT", 0, -10)
yellowfive@161 590 _lblBank:SetVisible(false)
yellowfive@161 591 _btnBank:SetVisible(false)
yellowfive@161 592 else
yellowfive@161 593
yellowfive@161 594 _panelContent:SetLayout("Fill")
yellowfive@161 595
yellowfive@161 596 local scroll = AceGUI:Create("AmrUiScrollFrame")
yellowfive@161 597 scroll:SetLayout("List")
yellowfive@161 598 _panelContent:AddChild(scroll)
yellowfive@161 599
yellowfive@161 600 -- render items currently in the player's inventory
yellowfive@161 601 local usedItems = {}
yellowfive@161 602 local bankCount = 0
yellowfive@161 603 local missingCount = 0
yellowfive@161 604
yellowfive@161 605 -- if we have any "keep" items, those are exact duplicates of ones to be junked,
yellowfive@161 606 -- be sure to "reserve" those first
yellowfive@161 607 if data.Keep then
yellowfive@161 608 for uniqueId, item in pairs(data.Keep) do
yellowfive@161 609 -- check if an exact match is in the player's bank data or equipped
yellowfive@161 610 local matchItem = findMatchingNonBagItem(item, usedItems)
yellowfive@161 611
yellowfive@161 612 -- if not, find one in the player's bags
yellowfive@161 613 if not matchItem then
yellowfive@161 614 matchItem = findMatchingBagItem(item, usedItems)
yellowfive@161 615 end
yellowfive@161 616
yellowfive@161 617 if not matchItem then
yellowfive@161 618 -- abort, player's data must be out of sync
yellowfive@161 619 local lbl = AceGUI:Create("AmrUiLabel")
yellowfive@161 620 _panelContent:AddChild(lbl)
yellowfive@161 621 lbl:SetWidth(380)
yellowfive@161 622 lbl:SetFont(Amr.CreateFont("Italic", 13, Amr.Colors.TextGray))
yellowfive@161 623 lbl:SetText(L.JunkOutOfSync)
yellowfive@161 624 lbl:SetPoint("TOPLEFT", _panelContent.content, "TOPLEFT", 0, -10)
yellowfive@161 625
yellowfive@161 626 _lblBank:SetVisible(false)
yellowfive@161 627 _btnBank:SetVisible(false)
yellowfive@161 628
yellowfive@161 629 return
yellowfive@161 630 end
yellowfive@161 631 end
yellowfive@161 632 end
yellowfive@161 633
yellowfive@161 634 -- now render any junk items in the player's bags, and a count of how many are elsewhere (usually bank)
yellowfive@161 635 for i, item in ipairs(data.Junk) do
yellowfive@161 636 local matchItem = findMatchingBagItem(item, usedItems)
yellowfive@161 637 if matchItem then
yellowfive@161 638 local itemLink = Amr.CreateItemLink(matchItem)
yellowfive@161 639 renderItem(matchItem, itemLink, scroll)
yellowfive@161 640 else
yellowfive@161 641 -- see if it is in the bank or equipped
yellowfive@161 642 matchItem = findMatchingNonBagItem(item, usedItems)
yellowfive@161 643 if matchItem then
yellowfive@161 644 bankCount = bankCount + 1
yellowfive@161 645 else
yellowfive@161 646 missingCount = missingCount + 1
yellowfive@161 647 end
yellowfive@161 648 end
yellowfive@161 649 end
yellowfive@161 650
yellowfive@161 651 _lblBank:SetText(L.JunkBankText(bankCount))
yellowfive@161 652 _lblBank:SetVisible(bankCount > 0)
yellowfive@161 653 _btnBank:SetVisible(bankCount > 0)
yellowfive@161 654 end
yellowfive@161 655 end
yellowfive@161 656
yellowfive@161 657 Amr:AddEventHandler("SCRAPPING_MACHINE_SHOW", function()
yellowfive@161 658 _isScrapOpen = true
yellowfive@161 659 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 660 Amr:ShowJunkWindow()
yellowfive@161 661 else
yellowfive@161 662 Amr:SetJunkUiState()
yellowfive@161 663 end
yellowfive@161 664 end)
yellowfive@161 665
yellowfive@161 666 Amr:AddEventHandler("SCRAPPING_MACHINE_CLOSE", function()
yellowfive@161 667 _isScrapOpen = false
yellowfive@161 668 if Amr.db.profile.options.junkVendor then
yellowfive@161 669 Amr:HideJunkWindow()
yellowfive@161 670 else
yellowfive@161 671 Amr:SetJunkUiState()
yellowfive@161 672 end
yellowfive@161 673 end)
yellowfive@161 674
yellowfive@161 675 Amr:AddEventHandler("MERCHANT_SHOW", function()
yellowfive@161 676 _isMerchantOpen = true
yellowfive@161 677 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 678 Amr:ShowJunkWindow()
yellowfive@161 679 else
yellowfive@161 680 Amr:SetJunkUiState()
yellowfive@161 681 end
yellowfive@161 682 end)
yellowfive@161 683
yellowfive@161 684 Amr:AddEventHandler("MERCHANT_CLOSED", function()
yellowfive@161 685 _isMerchantOpen = false
yellowfive@161 686 if Amr.db.profile.options.junkVendor then
yellowfive@161 687 Amr:HideJunkWindow()
yellowfive@161 688 else
yellowfive@161 689 Amr:SetJunkUiState()
yellowfive@161 690 end
yellowfive@161 691 end)
yellowfive@161 692
yellowfive@161 693 Amr:AddEventHandler("BANKFRAME_OPENED", function()
yellowfive@161 694 _isBankOpen = true
yellowfive@161 695 Amr:SetJunkUiState()
yellowfive@161 696 end)
yellowfive@161 697
yellowfive@161 698 Amr:AddEventHandler("BANKFRAME_CLOSED", function()
yellowfive@161 699 _isBankOpen = false
yellowfive@161 700 Amr:SetJunkUiState()
yellowfive@161 701 end)